changeset 7454:25b69fbfe80f

Merge
author chegar
date Tue, 23 Apr 2013 11:13:38 +0100
parents d0dbbdbb217f 62fb9e2b5da1
children 3197c702c8d1
files src/share/classes/java/util/logging/LogManager.java src/share/classes/sun/security/timestamp/TimestampToken.java
diffstat 84 files changed, 13055 insertions(+), 273 deletions(-) [+]
line wrap: on
line diff
--- a/src/macosx/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/macosx/classes/sun/util/locale/provider/HostLocaleProviderAdapterImpl.java	Tue Apr 23 11:13:38 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -520,14 +520,22 @@
     }
 
     private static boolean isSupportedCalendarLocale(Locale locale) {
-        Locale base = locale.stripExtensions();
+        Locale base = locale;
+
+        if (base.hasExtensions() || base.getVariant() != "") {
+            base = new Locale.Builder()
+                            .setLocale(locale)
+                            .clearExtensions()
+                            .build();
+        }
+
         if (!supportedLocaleSet.contains(base)) {
             return false;
         }
 
         String requestedCalType = locale.getUnicodeLocaleType("ca");
         String nativeCalType =
-            getCalendarID(locale.toLanguageTag()).replaceFirst("gregorian", "gregory");
+            getCalendarID(base.toLanguageTag()).replaceFirst("gregorian", "gregory");
 
         if (requestedCalType == null) {
             return Calendar.getAvailableCalendarTypes().contains(nativeCalType);
--- a/src/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java	Tue Apr 23 11:13:38 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, 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
@@ -241,14 +241,29 @@
         int off = secret.length >> 1;
         int seclen = off + (secret.length & 1);
 
+        byte[] secKey = secret;
+        int keyLen = seclen;
         byte[] output = new byte[outputLength];
 
         // P_MD5(S1, label + seed)
-        expand(md5, 16, secret, 0, seclen, labelBytes, seed, output,
+        // If we have a long secret, digest it first.
+        if (seclen > 64) {              // 64: block size of HMAC-MD5
+            md5.update(secret, 0, seclen);
+            secKey = md5.digest();
+            keyLen = secKey.length;
+        }
+        expand(md5, 16, secKey, 0, keyLen, labelBytes, seed, output,
             HMAC_ipad64.clone(), HMAC_opad64.clone());
 
         // P_SHA-1(S2, label + seed)
-        expand(sha, 20, secret, off, seclen, labelBytes, seed, output,
+        // If we have a long secret, digest it first.
+        if (seclen > 64) {              // 64: block size of HMAC-SHA1
+            sha.update(secret, off, seclen);
+            secKey = sha.digest();
+            keyLen = secKey.length;
+            off = 0;
+        }
+        expand(sha, 20, secKey, off, keyLen, labelBytes, seed, output,
             HMAC_ipad64.clone(), HMAC_opad64.clone());
 
         return output;
--- a/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java	Tue Apr 23 11:13:38 2013 +0100
@@ -60,6 +60,13 @@
     public X509Certificate getTimestampingAuthorityCertificate();
 
     /**
+     * Retrieves the TSAPolicyID for a Timestamping Authority (TSA).
+     *
+     * @return The TSAPolicyID. May be null.
+     */
+    public String getTSAPolicyID();
+
+    /**
      * Retrieves the JAR file's signature.
      *
      * @return The non-null array of signature bytes.
--- a/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/nio/file/attribute/BasicFileAttributeView.java	Tue Apr 23 11:13:38 2013 +0100
@@ -147,11 +147,11 @@
      * this method has no effect.
      *
      * <p> <b>Usage Example:</b>
-     * Suppose we want to change a file's creation time.
+     * Suppose we want to change a file's last access time.
      * <pre>
      *    Path path = ...
      *    FileTime time = ...
-     *    Files.getFileAttributeView(path, BasicFileAttributeView.class).setTimes(null, null, time);
+     *    Files.getFileAttributeView(path, BasicFileAttributeView.class).setTimes(null, time, null);
      * </pre>
      *
      * @param   lastModifiedTime
--- a/src/share/classes/java/util/ArrayDeque.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/util/ArrayDeque.java	Tue Apr 23 11:13:38 2013 +0100
@@ -33,7 +33,9 @@
  */
 
 package java.util;
-import java.io.*;
+
+import java.io.Serializable;
+import java.util.function.Consumer;
 
 /**
  * Resizable-array implementation of the {@link Deque} interface.  Array
@@ -44,16 +46,16 @@
  * {@link Stack} when used as a stack, and faster than {@link LinkedList}
  * when used as a queue.
  *
- * <p>Most <tt>ArrayDeque</tt> operations run in amortized constant time.
+ * <p>Most {@code ArrayDeque} operations run in amortized constant time.
  * Exceptions include {@link #remove(Object) remove}, {@link
  * #removeFirstOccurrence removeFirstOccurrence}, {@link #removeLastOccurrence
  * removeLastOccurrence}, {@link #contains contains}, {@link #iterator
  * iterator.remove()}, and the bulk operations, all of which run in linear
  * time.
  *
- * <p>The iterators returned by this class's <tt>iterator</tt> method are
+ * <p>The iterators returned by this class's {@code iterator} method are
  * <i>fail-fast</i>: If the deque is modified at any time after the iterator
- * is created, in any way except through the iterator's own <tt>remove</tt>
+ * is created, in any way except through the iterator's own {@code remove}
  * method, the iterator will generally throw a {@link
  * ConcurrentModificationException}.  Thus, in the face of concurrent
  * modification, the iterator fails quickly and cleanly, rather than risking
@@ -63,7 +65,7 @@
  * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
  * as it is, generally speaking, impossible to make any hard guarantees in the
  * presence of unsynchronized concurrent modification.  Fail-fast iterators
- * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
+ * throw {@code ConcurrentModificationException} on a best-effort basis.
  * Therefore, it would be wrong to write a program that depended on this
  * exception for its correctness: <i>the fail-fast behavior of iterators
  * should be used only to detect bugs.</i>
@@ -93,20 +95,20 @@
      * other.  We also guarantee that all array cells not holding
      * deque elements are always null.
      */
-    private transient E[] elements;
+    transient Object[] elements; // non-private to simplify nested class access
 
     /**
      * The index of the element at the head of the deque (which is the
      * element that would be removed by remove() or pop()); or an
      * arbitrary number equal to tail if the deque is empty.
      */
-    private transient int head;
+    transient int head;
 
     /**
      * The index at which the next element would be added to the tail
      * of the deque (via addLast(E), add(E), or push(E)).
      */
-    private transient int tail;
+    transient int tail;
 
     /**
      * The minimum capacity that we'll use for a newly created deque.
@@ -117,11 +119,10 @@
     // ******  Array allocation and resizing utilities ******
 
     /**
-     * Allocate empty array to hold the given number of elements.
+     * Allocates empty array to hold the given number of elements.
      *
      * @param numElements  the number of elements to hold
      */
-    @SuppressWarnings("unchecked")
     private void allocateElements(int numElements) {
         int initialCapacity = MIN_INITIAL_CAPACITY;
         // Find the best power of two to hold elements.
@@ -138,11 +139,11 @@
             if (initialCapacity < 0)   // Too many elements, must back off
                 initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements
         }
-        elements = (E[]) new Object[initialCapacity];
+        elements = new Object[initialCapacity];
     }
 
     /**
-     * Double the capacity of this deque.  Call only when full, i.e.,
+     * Doubles the capacity of this deque.  Call only when full, i.e.,
      * when head and tail have wrapped around to become equal.
      */
     private void doubleCapacity() {
@@ -153,8 +154,7 @@
         int newCapacity = n << 1;
         if (newCapacity < 0)
             throw new IllegalStateException("Sorry, deque too big");
-        @SuppressWarnings("unchecked")
-        E[] a = (E[]) new Object[newCapacity];
+        Object[] a = new Object[newCapacity];
         System.arraycopy(elements, p, a, 0, r);
         System.arraycopy(elements, 0, a, r, p);
         elements = a;
@@ -184,9 +184,8 @@
      * Constructs an empty array deque with an initial capacity
      * sufficient to hold 16 elements.
      */
-    @SuppressWarnings("unchecked")
     public ArrayDeque() {
-        elements = (E[]) new Object[16];
+        elements = new Object[16];
     }
 
     /**
@@ -252,7 +251,7 @@
      * Inserts the specified element at the front of this deque.
      *
      * @param e the element to add
-     * @return <tt>true</tt> (as specified by {@link Deque#offerFirst})
+     * @return {@code true} (as specified by {@link Deque#offerFirst})
      * @throws NullPointerException if the specified element is null
      */
     public boolean offerFirst(E e) {
@@ -264,7 +263,7 @@
      * Inserts the specified element at the end of this deque.
      *
      * @param e the element to add
-     * @return <tt>true</tt> (as specified by {@link Deque#offerLast})
+     * @return {@code true} (as specified by {@link Deque#offerLast})
      * @throws NullPointerException if the specified element is null
      */
     public boolean offerLast(E e) {
@@ -294,7 +293,9 @@
 
     public E pollFirst() {
         int h = head;
-        E result = elements[h]; // Element is null if deque empty
+        @SuppressWarnings("unchecked")
+        E result = (E) elements[h];
+        // Element is null if deque empty
         if (result == null)
             return null;
         elements[h] = null;     // Must null out slot
@@ -304,7 +305,8 @@
 
     public E pollLast() {
         int t = (tail - 1) & (elements.length - 1);
-        E result = elements[t];
+        @SuppressWarnings("unchecked")
+        E result = (E) elements[t];
         if (result == null)
             return null;
         elements[t] = null;
@@ -316,48 +318,53 @@
      * @throws NoSuchElementException {@inheritDoc}
      */
     public E getFirst() {
-        E x = elements[head];
-        if (x == null)
+        @SuppressWarnings("unchecked")
+        E result = (E) elements[head];
+        if (result == null)
             throw new NoSuchElementException();
-        return x;
+        return result;
     }
 
     /**
      * @throws NoSuchElementException {@inheritDoc}
      */
     public E getLast() {
-        E x = elements[(tail - 1) & (elements.length - 1)];
-        if (x == null)
+        @SuppressWarnings("unchecked")
+        E result = (E) elements[(tail - 1) & (elements.length - 1)];
+        if (result == null)
             throw new NoSuchElementException();
-        return x;
+        return result;
     }
 
+    @SuppressWarnings("unchecked")
     public E peekFirst() {
-        return elements[head]; // elements[head] is null if deque empty
+        // elements[head] is null if deque empty
+        return (E) elements[head];
     }
 
+    @SuppressWarnings("unchecked")
     public E peekLast() {
-        return elements[(tail - 1) & (elements.length - 1)];
+        return (E) elements[(tail - 1) & (elements.length - 1)];
     }
 
     /**
      * Removes the first occurrence of the specified element in this
      * deque (when traversing the deque from head to tail).
      * If the deque does not contain the element, it is unchanged.
-     * More formally, removes the first element <tt>e</tt> such that
-     * <tt>o.equals(e)</tt> (if such an element exists).
-     * Returns <tt>true</tt> if this deque contained the specified element
+     * More formally, removes the first element {@code e} such that
+     * {@code o.equals(e)} (if such an element exists).
+     * Returns {@code true} if this deque contained the specified element
      * (or equivalently, if this deque changed as a result of the call).
      *
      * @param o element to be removed from this deque, if present
-     * @return <tt>true</tt> if the deque contained the specified element
+     * @return {@code true} if the deque contained the specified element
      */
     public boolean removeFirstOccurrence(Object o) {
         if (o == null)
             return false;
         int mask = elements.length - 1;
         int i = head;
-        E x;
+        Object x;
         while ( (x = elements[i]) != null) {
             if (o.equals(x)) {
                 delete(i);
@@ -372,20 +379,20 @@
      * Removes the last occurrence of the specified element in this
      * deque (when traversing the deque from head to tail).
      * If the deque does not contain the element, it is unchanged.
-     * More formally, removes the last element <tt>e</tt> such that
-     * <tt>o.equals(e)</tt> (if such an element exists).
-     * Returns <tt>true</tt> if this deque contained the specified element
+     * More formally, removes the last element {@code e} such that
+     * {@code o.equals(e)} (if such an element exists).
+     * Returns {@code true} if this deque contained the specified element
      * (or equivalently, if this deque changed as a result of the call).
      *
      * @param o element to be removed from this deque, if present
-     * @return <tt>true</tt> if the deque contained the specified element
+     * @return {@code true} if the deque contained the specified element
      */
     public boolean removeLastOccurrence(Object o) {
         if (o == null)
             return false;
         int mask = elements.length - 1;
         int i = (tail - 1) & mask;
-        E x;
+        Object x;
         while ( (x = elements[i]) != null) {
             if (o.equals(x)) {
                 delete(i);
@@ -404,7 +411,7 @@
      * <p>This method is equivalent to {@link #addLast}.
      *
      * @param e the element to add
-     * @return <tt>true</tt> (as specified by {@link Collection#add})
+     * @return {@code true} (as specified by {@link Collection#add})
      * @throws NullPointerException if the specified element is null
      */
     public boolean add(E e) {
@@ -418,7 +425,7 @@
      * <p>This method is equivalent to {@link #offerLast}.
      *
      * @param e the element to add
-     * @return <tt>true</tt> (as specified by {@link Queue#offer})
+     * @return {@code true} (as specified by {@link Queue#offer})
      * @throws NullPointerException if the specified element is null
      */
     public boolean offer(E e) {
@@ -443,12 +450,12 @@
     /**
      * Retrieves and removes the head of the queue represented by this deque
      * (in other words, the first element of this deque), or returns
-     * <tt>null</tt> if this deque is empty.
+     * {@code null} if this deque is empty.
      *
      * <p>This method is equivalent to {@link #pollFirst}.
      *
      * @return the head of the queue represented by this deque, or
-     *         <tt>null</tt> if this deque is empty
+     *         {@code null} if this deque is empty
      */
     public E poll() {
         return pollFirst();
@@ -470,12 +477,12 @@
 
     /**
      * Retrieves, but does not remove, the head of the queue represented by
-     * this deque, or returns <tt>null</tt> if this deque is empty.
+     * this deque, or returns {@code null} if this deque is empty.
      *
      * <p>This method is equivalent to {@link #peekFirst}.
      *
      * @return the head of the queue represented by this deque, or
-     *         <tt>null</tt> if this deque is empty
+     *         {@code null} if this deque is empty
      */
     public E peek() {
         return peekFirst();
@@ -530,7 +537,7 @@
      */
     private boolean delete(int i) {
         checkInvariants();
-        final E[] elements = this.elements;
+        final Object[] elements = this.elements;
         final int mask = elements.length - 1;
         final int h = head;
         final int t = tail;
@@ -579,9 +586,9 @@
     }
 
     /**
-     * Returns <tt>true</tt> if this deque contains no elements.
+     * Returns {@code true} if this deque contains no elements.
      *
-     * @return <tt>true</tt> if this deque contains no elements
+     * @return {@code true} if this deque contains no elements
      */
     public boolean isEmpty() {
         return head == tail;
@@ -628,7 +635,8 @@
         public E next() {
             if (cursor == fence)
                 throw new NoSuchElementException();
-            E result = elements[cursor];
+            @SuppressWarnings("unchecked")
+            E result = (E) elements[cursor];
             // This check doesn't catch all possible comodifications,
             // but does catch the ones that corrupt traversal
             if (tail != fence || result == null)
@@ -647,6 +655,20 @@
             }
             lastRet = -1;
         }
+
+        public void forEachRemaining(Consumer<? super E> action) {
+            Objects.requireNonNull(action);
+            Object[] a = elements;
+            int m = a.length - 1, f = fence, i = cursor;
+            cursor = f;
+            while (i != f) {
+                @SuppressWarnings("unchecked") E e = (E)a[i];
+                i = (i + 1) & m;
+                if (e == null)
+                    throw new ConcurrentModificationException();
+                action.accept(e);
+            }
+        }
     }
 
     private class DescendingIterator implements Iterator<E> {
@@ -667,7 +689,8 @@
             if (cursor == fence)
                 throw new NoSuchElementException();
             cursor = (cursor - 1) & (elements.length - 1);
-            E result = elements[cursor];
+            @SuppressWarnings("unchecked")
+            E result = (E) elements[cursor];
             if (head != fence || result == null)
                 throw new ConcurrentModificationException();
             lastRet = cursor;
@@ -686,19 +709,19 @@
     }
 
     /**
-     * Returns <tt>true</tt> if this deque contains the specified element.
-     * More formally, returns <tt>true</tt> if and only if this deque contains
-     * at least one element <tt>e</tt> such that <tt>o.equals(e)</tt>.
+     * Returns {@code true} if this deque contains the specified element.
+     * More formally, returns {@code true} if and only if this deque contains
+     * at least one element {@code e} such that {@code o.equals(e)}.
      *
      * @param o object to be checked for containment in this deque
-     * @return <tt>true</tt> if this deque contains the specified element
+     * @return {@code true} if this deque contains the specified element
      */
     public boolean contains(Object o) {
         if (o == null)
             return false;
         int mask = elements.length - 1;
         int i = head;
-        E x;
+        Object x;
         while ( (x = elements[i]) != null) {
             if (o.equals(x))
                 return true;
@@ -710,15 +733,15 @@
     /**
      * Removes a single instance of the specified element from this deque.
      * If the deque does not contain the element, it is unchanged.
-     * More formally, removes the first element <tt>e</tt> such that
-     * <tt>o.equals(e)</tt> (if such an element exists).
-     * Returns <tt>true</tt> if this deque contained the specified element
+     * More formally, removes the first element {@code e} such that
+     * {@code o.equals(e)} (if such an element exists).
+     * Returns {@code true} if this deque contained the specified element
      * (or equivalently, if this deque changed as a result of the call).
      *
-     * <p>This method is equivalent to {@link #removeFirstOccurrence}.
+     * <p>This method is equivalent to {@link #removeFirstOccurrence(Object)}.
      *
      * @param o element to be removed from this deque, if present
-     * @return <tt>true</tt> if this deque contained the specified element
+     * @return {@code true} if this deque contained the specified element
      */
     public boolean remove(Object o) {
         return removeFirstOccurrence(o);
@@ -770,22 +793,21 @@
      * <p>If this deque fits in the specified array with room to spare
      * (i.e., the array has more elements than this deque), the element in
      * the array immediately following the end of the deque is set to
-     * <tt>null</tt>.
+     * {@code null}.
      *
      * <p>Like the {@link #toArray()} method, this method acts as bridge between
      * array-based and collection-based APIs.  Further, this method allows
      * precise control over the runtime type of the output array, and may,
      * under certain circumstances, be used to save allocation costs.
      *
-     * <p>Suppose <tt>x</tt> is a deque known to contain only strings.
+     * <p>Suppose {@code x} is a deque known to contain only strings.
      * The following code can be used to dump the deque into a newly
-     * allocated array of <tt>String</tt>:
+     * allocated array of {@code String}:
      *
-     * <pre>
-     *     String[] y = x.toArray(new String[0]);</pre>
+     *  <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
      *
-     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
-     * <tt>toArray()</tt>.
+     * Note that {@code toArray(new Object[0])} is identical in function to
+     * {@code toArray()}.
      *
      * @param a the array into which the elements of the deque are to
      *          be stored, if it is big enough; otherwise, a new array of the
@@ -818,28 +840,25 @@
     public ArrayDeque<E> clone() {
         try {
             @SuppressWarnings("unchecked")
-                ArrayDeque<E> result = (ArrayDeque<E>) super.clone();
+            ArrayDeque<E> result = (ArrayDeque<E>) super.clone();
             result.elements = Arrays.copyOf(elements, elements.length);
             return result;
-
         } catch (CloneNotSupportedException e) {
             throw new AssertionError();
         }
     }
 
-    /**
-     * Appease the serialization gods.
-     */
     private static final long serialVersionUID = 2340985798034038923L;
 
     /**
-     * Serialize this deque.
+     * Saves this deque to a stream (that is, serializes it).
      *
-     * @serialData The current size (<tt>int</tt>) of the deque,
+     * @serialData The current size ({@code int}) of the deque,
      * followed by all of its elements (each an object reference) in
      * first-to-last order.
      */
-    private void writeObject(ObjectOutputStream s) throws IOException {
+    private void writeObject(java.io.ObjectOutputStream s)
+            throws java.io.IOException {
         s.defaultWriteObject();
 
         // Write out size
@@ -852,11 +871,10 @@
     }
 
     /**
-     * Deserialize this deque.
+     * Reconstitutes this deque from a stream (that is, deserializes it).
      */
-    @SuppressWarnings("unchecked")
-    private void readObject(ObjectInputStream s)
-            throws IOException, ClassNotFoundException {
+    private void readObject(java.io.ObjectInputStream s)
+            throws java.io.IOException, ClassNotFoundException {
         s.defaultReadObject();
 
         // Read in size and allocate array
@@ -867,6 +885,88 @@
 
         // Read in all elements in the proper order.
         for (int i = 0; i < size; i++)
-            elements[i] = (E)s.readObject();
+            elements[i] = s.readObject();
     }
+
+    public Spliterator<E> spliterator() {
+        return new DeqSpliterator<E>(this, -1, -1);
+    }
+
+    static final class DeqSpliterator<E> implements Spliterator<E> {
+        private final ArrayDeque<E> deq;
+        private int fence;  // -1 until first use
+        private int index;  // current index, modified on traverse/split
+
+        /** Creates new spliterator covering the given array and range */
+        DeqSpliterator(ArrayDeque<E> deq, int origin, int fence) {
+            this.deq = deq;
+            this.index = origin;
+            this.fence = fence;
+        }
+
+        private int getFence() { // force initialization
+            int t;
+            if ((t = fence) < 0) {
+                t = fence = deq.tail;
+                index = deq.head;
+            }
+            return t;
+        }
+
+        public DeqSpliterator<E> trySplit() {
+            int t = getFence(), h = index, n = deq.elements.length;
+            if (h != t && ((h + 1) & (n - 1)) != t) {
+                if (h > t)
+                    t += n;
+                int m = ((h + t) >>> 1) & (n - 1);
+                return new DeqSpliterator<>(deq, h, index = m);
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super E> consumer) {
+            if (consumer == null)
+                throw new NullPointerException();
+            Object[] a = deq.elements;
+            int m = a.length - 1, f = getFence(), i = index;
+            index = f;
+            while (i != f) {
+                @SuppressWarnings("unchecked") E e = (E)a[i];
+                i = (i + 1) & m;
+                if (e == null)
+                    throw new ConcurrentModificationException();
+                consumer.accept(e);
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super E> consumer) {
+            if (consumer == null)
+                throw new NullPointerException();
+            Object[] a = deq.elements;
+            int m = a.length - 1, f = getFence(), i = index;
+            if (i != fence) {
+                @SuppressWarnings("unchecked") E e = (E)a[i];
+                index = (i + 1) & m;
+                if (e == null)
+                    throw new ConcurrentModificationException();
+                consumer.accept(e);
+                return true;
+            }
+            return false;
+        }
+
+        public long estimateSize() {
+            int n = getFence() - index;
+            if (n < 0)
+                n += deq.elements.length;
+            return (long) n;
+        }
+
+        @Override
+        public int characteristics() {
+            return Spliterator.ORDERED | Spliterator.SIZED |
+                Spliterator.NONNULL | Spliterator.SUBSIZED;
+        }
+    }
+
 }
--- a/src/share/classes/java/util/ArrayList.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/util/ArrayList.java	Tue Apr 23 11:13:38 2013 +0100
@@ -25,6 +25,14 @@
 
 package java.util;
 
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+import java.util.function.UnaryOperator;
+
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+import java.util.function.UnaryOperator;
+
 /**
  * Resizable-array implementation of the <tt>List</tt> interface.  Implements
  * all optional list operations, and permits all elements, including
@@ -120,7 +128,7 @@
      * empty ArrayList with elementData == EMPTY_ELEMENTDATA will be expanded to
      * DEFAULT_CAPACITY when the first element is added.
      */
-    private transient Object[] elementData;
+    transient Object[] elementData; // non-private to simplify nested class access
 
     /**
      * The size of the ArrayList (the number of elements it contains).
@@ -853,6 +861,27 @@
             }
         }
 
+        @Override
+        @SuppressWarnings("unchecked")
+        public void forEachRemaining(Consumer<? super E> consumer) {
+            Objects.requireNonNull(consumer);
+            final int size = ArrayList.this.size;
+            int i = cursor;
+            if (i >= size) {
+                return;
+            }
+            final Object[] elementData = ArrayList.this.elementData;
+            if (i >= elementData.length) {
+                throw new ConcurrentModificationException();
+            }
+            while (i != size && modCount == expectedModCount) {
+                consumer.accept((E) elementData[i++]);
+            }
+            // update once at end of iteration to reduce heap write traffic
+            lastRet = cursor = i;
+            checkForComodification();
+        }
+
         final void checkForComodification() {
             if (modCount != expectedModCount)
                 throw new ConcurrentModificationException();
@@ -1088,6 +1117,26 @@
                     return (E) elementData[offset + (lastRet = i)];
                 }
 
+                @SuppressWarnings("unchecked")
+                public void forEachRemaining(Consumer<? super E> consumer) {
+                    Objects.requireNonNull(consumer);
+                    final int size = SubList.this.size;
+                    int i = cursor;
+                    if (i >= size) {
+                        return;
+                    }
+                    final Object[] elementData = ArrayList.this.elementData;
+                    if (offset + i >= elementData.length) {
+                        throw new ConcurrentModificationException();
+                    }
+                    while (i != size && modCount == expectedModCount) {
+                        consumer.accept((E) elementData[offset + (i++)]);
+                    }
+                    // update once at end of iteration to reduce heap write traffic
+                    lastRet = cursor = i;
+                    checkForComodification();
+                }
+
                 public int nextIndex() {
                     return cursor;
                 }
@@ -1167,5 +1216,217 @@
             if (ArrayList.this.modCount != this.modCount)
                 throw new ConcurrentModificationException();
         }
+
+        public Spliterator<E> spliterator() {
+            checkForComodification();
+            return new ArrayListSpliterator<E>(ArrayList.this, offset,
+                                               offset + this.size, this.modCount);
+        }
+    }
+
+    @Override
+    public void forEach(Consumer<? super E> action) {
+        Objects.requireNonNull(action);
+        final int expectedModCount = modCount;
+        @SuppressWarnings("unchecked")
+        final E[] elementData = (E[]) this.elementData;
+        final int size = this.size;
+        for (int i=0; modCount == expectedModCount && i < size; i++) {
+            action.accept(elementData[i]);
+        }
+        if (modCount != expectedModCount) {
+            throw new ConcurrentModificationException();
+        }
+    }
+
+    public Spliterator<E> spliterator() {
+        return new ArrayListSpliterator<>(this, 0, -1, 0);
+    }
+
+    /** Index-based split-by-two, lazily initialized Spliterator */
+    static final class ArrayListSpliterator<E> implements Spliterator<E> {
+
+        /*
+         * If ArrayLists were immutable, or structurally immutable (no
+         * adds, removes, etc), we could implement their spliterators
+         * with Arrays.spliterator. Instead we detect as much
+         * interference during traversal as practical without
+         * sacrificing much performance. We rely primarily on
+         * modCounts. These are not guaranteed to detect concurrency
+         * violations, and are sometimes overly conservative about
+         * within-thread interference, but detect enough problems to
+         * be worthwhile in practice. To carry this out, we (1) lazily
+         * initialize fence and expectedModCount until the latest
+         * point that we need to commit to the state we are checking
+         * against; thus improving precision.  (This doesn't apply to
+         * SubLists, that create spliterators with current non-lazy
+         * values).  (2) We perform only a single
+         * ConcurrentModificationException check at the end of forEach
+         * (the most performance-sensitive method). When using forEach
+         * (as opposed to iterators), we can normally only detect
+         * interference after actions, not before. Further
+         * CME-triggering checks apply to all other possible
+         * violations of assumptions for example null or too-small
+         * elementData array given its size(), that could only have
+         * occurred due to interference.  This allows the inner loop
+         * of forEach to run without any further checks, and
+         * simplifies lambda-resolution. While this does entail a
+         * number of checks, note that in the common case of
+         * list.stream().forEach(a), no checks or other computation
+         * occur anywhere other than inside forEach itself.  The other
+         * less-often-used methods cannot take advantage of most of
+         * these streamlinings.
+         */
+
+        private final ArrayList<E> list;
+        private int index; // current index, modified on advance/split
+        private int fence; // -1 until used; then one past last index
+        private int expectedModCount; // initialized when fence set
+
+        /** Create new spliterator covering the given  range */
+        ArrayListSpliterator(ArrayList<E> list, int origin, int fence,
+                             int expectedModCount) {
+            this.list = list; // OK if null unless traversed
+            this.index = origin;
+            this.fence = fence;
+            this.expectedModCount = expectedModCount;
+        }
+
+        private int getFence() { // initialize fence to size on first use
+            int hi; // (a specialized variant appears in method forEach)
+            ArrayList<E> lst;
+            if ((hi = fence) < 0) {
+                if ((lst = list) == null)
+                    hi = fence = 0;
+                else {
+                    expectedModCount = lst.modCount;
+                    hi = fence = lst.size;
+                }
+            }
+            return hi;
+        }
+
+        public ArrayListSpliterator<E> trySplit() {
+            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
+            return (lo >= mid) ? null : // divide range in half unless too small
+                new ArrayListSpliterator<E>(list, lo, index = mid,
+                                            expectedModCount);
+        }
+
+        public boolean tryAdvance(Consumer<? super E> action) {
+            if (action == null)
+                throw new NullPointerException();
+            int hi = getFence(), i = index;
+            if (i < hi) {
+                index = i + 1;
+                @SuppressWarnings("unchecked") E e = (E)list.elementData[i];
+                action.accept(e);
+                if (list.modCount != expectedModCount)
+                    throw new ConcurrentModificationException();
+                return true;
+            }
+            return false;
+        }
+
+        public void forEachRemaining(Consumer<? super E> action) {
+            int i, hi, mc; // hoist accesses and checks from loop
+            ArrayList<E> lst; Object[] a;
+            if (action == null)
+                throw new NullPointerException();
+            if ((lst = list) != null && (a = lst.elementData) != null) {
+                if ((hi = fence) < 0) {
+                    mc = lst.modCount;
+                    hi = lst.size;
+                }
+                else
+                    mc = expectedModCount;
+                if ((i = index) >= 0 && (index = hi) <= a.length) {
+                    for (; i < hi; ++i) {
+                        @SuppressWarnings("unchecked") E e = (E) a[i];
+                        action.accept(e);
+                    }
+                    if (lst.modCount == mc)
+                        return;
+                }
+            }
+            throw new ConcurrentModificationException();
+        }
+
+        public long estimateSize() {
+            return (long) (getFence() - index);
+        }
+
+        public int characteristics() {
+            return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
+        }
+    }
+
+    @Override
+    public boolean removeIf(Predicate<? super E> filter) {
+        Objects.requireNonNull(filter);
+        // figure out which elements are to be removed
+        // any exception thrown from the filter predicate at this stage
+        // will leave the collection unmodified
+        int removeCount = 0;
+        final BitSet removeSet = new BitSet(size);
+        final int expectedModCount = modCount;
+        final int size = this.size;
+        for (int i=0; modCount == expectedModCount && i < size; i++) {
+            @SuppressWarnings("unchecked")
+            final E element = (E) elementData[i];
+            if (filter.test(element)) {
+                removeSet.set(i);
+                removeCount++;
+            }
+        }
+        if (modCount != expectedModCount) {
+            throw new ConcurrentModificationException();
+        }
+
+        // shift surviving elements left over the spaces left by removed elements
+        final boolean anyToRemove = removeCount > 0;
+        if (anyToRemove) {
+            final int newSize = size - removeCount;
+            for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
+                i = removeSet.nextClearBit(i);
+                elementData[j] = elementData[i];
+            }
+            for (int k=newSize; k < size; k++) {
+                elementData[k] = null;  // Let gc do its work
+            }
+            this.size = newSize;
+            if (modCount != expectedModCount) {
+                throw new ConcurrentModificationException();
+            }
+            modCount++;
+        }
+
+        return anyToRemove;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public void replaceAll(UnaryOperator<E> operator) {
+        Objects.requireNonNull(operator);
+        final int expectedModCount = modCount;
+        final int size = this.size;
+        for (int i=0; modCount == expectedModCount && i < size; i++) {
+            elementData[i] = operator.apply((E) elementData[i]);
+        }
+        if (modCount != expectedModCount) {
+            throw new ConcurrentModificationException();
+        }
+        modCount++;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public void sort(Comparator<? super E> c) {
+        final int expectedModCount = modCount;
+        Arrays.sort((E[]) elementData, 0, size, c);
+        if (modCount != expectedModCount) {
+            throw new ConcurrentModificationException();
+        }
+        modCount++;
     }
 }
--- a/src/share/classes/java/util/Collection.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/util/Collection.java	Tue Apr 23 11:13:38 2013 +0100
@@ -25,6 +25,8 @@
 
 package java.util;
 
+import java.util.function.Predicate;
+
 /**
  * The root interface in the <i>collection hierarchy</i>.  A collection
  * represents a group of objects, known as its <i>elements</i>.  Some
@@ -373,6 +375,40 @@
     boolean removeAll(Collection<?> c);
 
     /**
+     * Removes all of the elements of this collection that satisfy the given
+     * predicate.  Errors or runtime exceptions thrown by the predicate are
+     * relayed to the caller.
+     *
+     * @implSpec
+     * The default implementation traverses all elements of the collection using
+     * its {@link #iterator}.  Each matching element is removed using
+     * {@link Iterator#remove()}.  If the collection's iterator does not
+     * support removal then an {@code UnsupportedOperationException} will be
+     * thrown on the first matching element.
+     *
+     * @param filter a predicate which returns {@code true} for elements to be
+     *        removed
+     * @return {@code true} if any elements were removed
+     * @throws NullPointerException if the specified filter is null
+     * @throws UnsupportedOperationException if the {@code remove}
+     *         method is not supported by this collection's
+     *         {@link #iterator}
+     * @since 1.8
+     */
+    default boolean removeIf(Predicate<? super E> filter) {
+        Objects.requireNonNull(filter);
+        boolean removed = false;
+        final Iterator<E> each = iterator();
+        while (each.hasNext()) {
+            if (filter.test(each.next())) {
+                each.remove();
+                removed = true;
+            }
+        }
+        return removed;
+    }
+
+    /**
      * Retains only the elements in this collection that are contained in the
      * specified collection (optional operation).  In other words, removes from
      * this collection all of its elements that are not contained in the
--- a/src/share/classes/java/util/Collections.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/util/Collections.java	Tue Apr 23 11:13:38 2013 +0100
@@ -30,7 +30,10 @@
 import java.lang.reflect.Array;
 import java.util.function.BiConsumer;
 import java.util.function.BiFunction;
+import java.util.function.Consumer;
 import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.function.UnaryOperator;
 
 /**
  * This class consists exclusively of static methods that operate on or return
@@ -1085,6 +1088,11 @@
                 public void remove() {
                     throw new UnsupportedOperationException();
                 }
+                @Override
+                public void forEachRemaining(Consumer<? super E> action) {
+                    // Use backing collection version
+                    i.forEachRemaining(action);
+                }
             };
         }
 
@@ -1110,6 +1118,21 @@
         public void clear() {
             throw new UnsupportedOperationException();
         }
+
+        // Override default methods in Collection
+        @Override
+        public void forEach(Consumer<? super E> action) {
+            c.forEach(action);
+        }
+        @Override
+        public boolean removeIf(Predicate<? super E> filter) {
+            throw new UnsupportedOperationException();
+        }
+        @Override
+        public Spliterator<E> spliterator() {
+            return (Spliterator<E>)c.spliterator();
+        }
+
     }
 
     /**
@@ -1240,6 +1263,16 @@
         public boolean addAll(int index, Collection<? extends E> c) {
             throw new UnsupportedOperationException();
         }
+
+        @Override
+        public void replaceAll(UnaryOperator<E> operator) {
+            throw new UnsupportedOperationException();
+        }
+        @Override
+        public void sort(Comparator<? super E> c) {
+            throw new UnsupportedOperationException();
+        }
+
         public ListIterator<E> listIterator()   {return listIterator(0);}
 
         public ListIterator<E> listIterator(final int index) {
@@ -1263,6 +1296,11 @@
                 public void add(E e) {
                     throw new UnsupportedOperationException();
                 }
+
+                @Override
+                public void forEachRemaining(Consumer<? super E> action) {
+                    i.forEachRemaining(action);
+                }
             };
         }
 
@@ -1642,7 +1680,8 @@
      * through the returned collection.<p>
      *
      * It is imperative that the user manually synchronize on the returned
-     * collection when iterating over it:
+     * collection when traversing it via {@link Iterator} or
+     * {@link Spliterator}:
      * <pre>
      *  Collection c = Collections.synchronizedCollection(myCollection);
      *     ...
@@ -1739,6 +1778,19 @@
         public String toString() {
             synchronized (mutex) {return c.toString();}
         }
+        // Override default methods in Collection
+        @Override
+        public void forEach(Consumer<? super E> consumer) {
+            synchronized (mutex) {c.forEach(consumer);}
+        }
+        @Override
+        public boolean removeIf(Predicate<? super E> filter) {
+            synchronized (mutex) {return c.removeIf(filter);}
+        }
+        @Override
+        public Spliterator<E> spliterator() {
+            return c.spliterator(); // Must be manually synched by user!
+        }
         private void writeObject(ObjectOutputStream s) throws IOException {
             synchronized (mutex) {s.defaultWriteObject();}
         }
@@ -1996,6 +2048,15 @@
             }
         }
 
+        @Override
+        public void replaceAll(UnaryOperator<E> operator) {
+            synchronized (mutex) {list.replaceAll(operator);}
+        }
+        @Override
+        public void sort(Comparator<? super E> c) {
+            synchronized (mutex) {list.sort(c);}
+        }
+
         /**
          * SynchronizedRandomAccessList instances are serialized as
          * SynchronizedList instances to allow them to be deserialized
@@ -2492,6 +2553,16 @@
             // element as we added it)
             return c.addAll(checkedCopyOf(coll));
         }
+
+        // Override default methods in Collection
+        @Override
+        public void forEach(Consumer<? super E> action) {c.forEach(action);}
+        @Override
+        public boolean removeIf(Predicate<? super E> filter) {
+            return c.removeIf(filter);
+        }
+        @Override
+        public Spliterator<E> spliterator() {return c.spliterator();}
     }
 
     /**
@@ -2747,12 +2818,26 @@
                     typeCheck(e);
                     i.add(e);
                 }
+
+                @Override
+                public void forEachRemaining(Consumer<? super E> action) {
+                    i.forEachRemaining(action);
+                }
             };
         }
 
         public List<E> subList(int fromIndex, int toIndex) {
             return new CheckedList<>(list.subList(fromIndex, toIndex), type);
         }
+
+        @Override
+        public void replaceAll(UnaryOperator<E> operator) {
+            list.replaceAll(operator);
+        }
+        @Override
+        public void sort(Comparator<? super E> c) {
+            list.sort(c);
+        }
     }
 
     /**
@@ -3276,6 +3361,10 @@
         public boolean hasNext() { return false; }
         public E next() { throw new NoSuchElementException(); }
         public void remove() { throw new IllegalStateException(); }
+        @Override
+        public void forEachRemaining(Consumer<? super E> action) {
+            Objects.requireNonNull(action);
+        }
     }
 
     /**
@@ -3416,6 +3505,19 @@
             return a;
         }
 
+        // Override default methods in Collection
+        @Override
+        public void forEach(Consumer<? super E> action) {
+            Objects.requireNonNull(action);
+        }
+        @Override
+        public boolean removeIf(Predicate<? super E> filter) {
+            Objects.requireNonNull(filter);
+            return false;
+        }
+        @Override
+        public Spliterator<E> spliterator() { return Spliterators.emptySpliterator(); }
+
         // Preserves singleton property
         private Object readResolve() {
             return EMPTY_SET;
@@ -3523,6 +3625,21 @@
         public E last() {
             throw new NoSuchElementException();
         }
+
+        // Override default methods in Collection
+        @Override
+        public void forEach(Consumer<? super E> action) {
+            Objects.requireNonNull(action);
+        }
+
+        @Override
+        public boolean removeIf(Predicate<? super E> filter) {
+            Objects.requireNonNull(filter);
+            return false;
+        }
+
+        @Override
+        public Spliterator<E> spliterator() { return Spliterators.emptySpliterator(); }
     }
 
     /**
@@ -3592,6 +3709,29 @@
 
         public int hashCode() { return 1; }
 
+        @Override
+        public boolean removeIf(Predicate<? super E> filter) {
+            Objects.requireNonNull(filter);
+            return false;
+        }
+        @Override
+        public void replaceAll(UnaryOperator<E> operator) {
+            Objects.requireNonNull(operator);
+        }
+        @Override
+        public void sort(Comparator<? super E> c) {
+            Objects.requireNonNull(c);
+        }
+
+        // Override default methods in Collection
+        @Override
+        public void forEach(Consumer<? super E> action) {
+            Objects.requireNonNull(action);
+        }
+
+        @Override
+        public Spliterator<E> spliterator() { return Spliterators.emptySpliterator(); }
+
         // Preserves singleton property
         private Object readResolve() {
             return EMPTY_LIST;
@@ -3747,6 +3887,60 @@
             public void remove() {
                 throw new UnsupportedOperationException();
             }
+            @Override
+            public void forEachRemaining(Consumer<? super E> action) {
+                Objects.requireNonNull(action);
+                if (hasNext) {
+                    action.accept(e);
+                    hasNext = false;
+                }
+            }
+        };
+    }
+
+    /**
+     * Creates a {@code Spliterator} with only the specified element
+     *
+     * @param <T> Type of elements
+     * @return A singleton {@code Spliterator}
+     */
+    static <T> Spliterator<T> singletonSpliterator(final T element) {
+        return new Spliterator<T>() {
+            long est = 1;
+
+            @Override
+            public Spliterator<T> trySplit() {
+                return null;
+            }
+
+            @Override
+            public boolean tryAdvance(Consumer<? super T> consumer) {
+                Objects.requireNonNull(consumer);
+                if (est > 0) {
+                    est--;
+                    consumer.accept(element);
+                    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 value = (element != null) ? Spliterator.NONNULL : 0;
+
+                return value | Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.IMMUTABLE |
+                       Spliterator.DISTINCT | Spliterator.ORDERED;
+            }
         };
     }
 
@@ -3770,6 +3964,20 @@
         public int size() {return 1;}
 
         public boolean contains(Object o) {return eq(o, element);}
+
+        // Override default methods for Collection
+        @Override
+        public void forEach(Consumer<? super E> action) {
+            action.accept(element);
+        }
+        @Override
+        public Spliterator<E> spliterator() {
+            return singletonSpliterator(element);
+        }
+        @Override
+        public boolean removeIf(Predicate<? super E> filter) {
+            throw new UnsupportedOperationException();
+        }
     }
 
     /**
@@ -3810,6 +4018,27 @@
               throw new IndexOutOfBoundsException("Index: "+index+", Size: 1");
             return element;
         }
+
+        // Override default methods for Collection
+        @Override
+        public void forEach(Consumer<? super E> action) {
+            action.accept(element);
+        }
+        @Override
+        public boolean removeIf(Predicate<? super E> filter) {
+            throw new UnsupportedOperationException();
+        }
+        @Override
+        public void replaceAll(UnaryOperator<E> operator) {
+            throw new UnsupportedOperationException();
+        }
+        @Override
+        public void sort(Comparator<? super E> c) {
+        }
+        @Override
+        public Spliterator<E> spliterator() {
+            return singletonSpliterator(element);
+        }
     }
 
     /**
@@ -4408,6 +4637,19 @@
         public boolean retainAll(Collection<?> c)   {return s.retainAll(c);}
         // addAll is the only inherited implementation
 
+        // Override default methods in Collection
+        @Override
+        public void forEach(Consumer<? super E> action) {
+            s.forEach(action);
+        }
+        @Override
+        public boolean removeIf(Predicate<? super E> filter) {
+            return s.removeIf(filter);
+        }
+
+        @Override
+        public Spliterator<E> spliterator() {return s.spliterator();}
+
         private static final long serialVersionUID = 2454657854757543876L;
 
         private void readObject(java.io.ObjectInputStream stream)
@@ -4466,5 +4708,15 @@
         public boolean removeAll(Collection<?> c)   {return q.removeAll(c);}
         public boolean retainAll(Collection<?> c)   {return q.retainAll(c);}
         // We use inherited addAll; forwarding addAll would be wrong
+
+        // Override default methods in Collection
+        @Override
+        public void forEach(Consumer<? super E> action) {q.forEach(action);}
+        @Override
+        public Spliterator<E> spliterator() {return q.spliterator();}
+        @Override
+        public boolean removeIf(Predicate<? super E> filter) {
+            return q.removeIf(filter);
+        }
     }
 }
--- a/src/share/classes/java/util/Currency.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/util/Currency.java	Tue Apr 23 11:13:38 2013 +0100
@@ -47,9 +47,8 @@
 
 /**
  * Represents a currency. Currencies are identified by their ISO 4217 currency
- * codes. Visit the <a href="http://www.iso.org/iso/en/prods-services/popstds/currencycodes.html">
- * ISO web site</a> for more information, including a table of
- * currency codes.
+ * codes. Visit the <a href="http://www.iso.org/iso/home/standards/currency_codes.htm">
+ * ISO web site</a> for more information.
  * <p>
  * The class is designed so that there's never more than one
  * <code>Currency</code> instance for any given currency. Therefore, there's
--- a/src/share/classes/java/util/HashMap.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/util/HashMap.java	Tue Apr 23 11:13:38 2013 +0100
@@ -1230,6 +1230,14 @@
         public void clear() {
             HashMap.this.clear();
         }
+
+        public Spliterator<K> spliterator() {
+            if (HashMap.this.getClass() == HashMap.class)
+                return new KeySpliterator<K,V>(HashMap.this, 0, -1, 0, 0);
+            else
+                return Spliterators.spliterator
+                        (this, Spliterator.SIZED | Spliterator.DISTINCT);
+        }
     }
 
     /**
@@ -1263,6 +1271,14 @@
         public void clear() {
             HashMap.this.clear();
         }
+
+        public Spliterator<V> spliterator() {
+            if (HashMap.this.getClass() == HashMap.class)
+                return new ValueSpliterator<K,V>(HashMap.this, 0, -1, 0, 0);
+            else
+                return Spliterators.spliterator
+                        (this, Spliterator.SIZED);
+        }
     }
 
     /**
@@ -1310,6 +1326,14 @@
         public void clear() {
             HashMap.this.clear();
         }
+
+        public Spliterator<Map.Entry<K,V>> spliterator() {
+            if (HashMap.this.getClass() == HashMap.class)
+                return new EntrySpliterator<K,V>(HashMap.this, 0, -1, 0, 0);
+            else
+                return Spliterators.spliterator
+                        (this, Spliterator.SIZED | Spliterator.DISTINCT);
+        }
     }
 
     /**
@@ -1406,4 +1430,257 @@
     // These methods are used when serializing HashSets
     int   capacity()     { return table.length; }
     float loadFactor()   { return loadFactor;   }
+
+    /**
+     * Standin until HM overhaul; based loosely on Weak and Identity HM.
+     */
+    static class HashMapSpliterator<K,V> {
+        final HashMap<K,V> map;
+        HashMap.Entry<K,V> current; // current node
+        int index;                  // current index, modified on advance/split
+        int fence;                  // one past last index
+        int est;                    // size estimate
+        int expectedModCount;       // for comodification checks
+
+        HashMapSpliterator(HashMap<K,V> m, int origin,
+                               int fence, int est,
+                               int expectedModCount) {
+            this.map = m;
+            this.index = origin;
+            this.fence = fence;
+            this.est = est;
+            this.expectedModCount = expectedModCount;
+        }
+
+        final int getFence() { // initialize fence and size on first use
+            int hi;
+            if ((hi = fence) < 0) {
+                HashMap<K,V> m = map;
+                est = m.size;
+                expectedModCount = m.modCount;
+                hi = fence = m.table.length;
+            }
+            return hi;
+        }
+
+        public final long estimateSize() {
+            getFence(); // force init
+            return (long) est;
+        }
+    }
+
+    static final class KeySpliterator<K,V>
+        extends HashMapSpliterator<K,V>
+        implements Spliterator<K> {
+        KeySpliterator(HashMap<K,V> m, int origin, int fence, int est,
+                       int expectedModCount) {
+            super(m, origin, fence, est, expectedModCount);
+        }
+
+        public KeySpliterator<K,V> trySplit() {
+            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
+            return (lo >= mid || current != null) ? null :
+                new KeySpliterator<K,V>(map, lo, index = mid, est >>>= 1,
+                                        expectedModCount);
+        }
+
+        @SuppressWarnings("unchecked")
+        public void forEachRemaining(Consumer<? super K> action) {
+            int i, hi, mc;
+            if (action == null)
+                throw new NullPointerException();
+            HashMap<K,V> m = map;
+            HashMap.Entry<K,V>[] tab = (HashMap.Entry<K,V>[])m.table;
+            if ((hi = fence) < 0) {
+                mc = expectedModCount = m.modCount;
+                hi = fence = tab.length;
+            }
+            else
+                mc = expectedModCount;
+            if (tab.length >= hi && (i = index) >= 0 && i < (index = hi)) {
+                HashMap.Entry<K,V> p = current;
+                do {
+                    if (p == null)
+                        p = tab[i++];
+                    else {
+                        action.accept(p.getKey());
+                        p = p.next;
+                    }
+                } while (p != null || i < hi);
+                if (m.modCount != mc)
+                    throw new ConcurrentModificationException();
+            }
+        }
+
+        @SuppressWarnings("unchecked")
+        public boolean tryAdvance(Consumer<? super K> action) {
+            int hi;
+            if (action == null)
+                throw new NullPointerException();
+            HashMap.Entry<K,V>[] tab = (HashMap.Entry<K,V>[])map.table;
+            if (tab.length >= (hi = getFence()) && index >= 0) {
+                while (current != null || index < hi) {
+                    if (current == null)
+                        current = tab[index++];
+                    else {
+                        K k = current.getKey();
+                        current = current.next;
+                        action.accept(k);
+                        if (map.modCount != expectedModCount)
+                            throw new ConcurrentModificationException();
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+
+        public int characteristics() {
+            return (fence < 0 || est == map.size ? Spliterator.SIZED : 0) |
+                Spliterator.DISTINCT;
+        }
+    }
+
+    static final class ValueSpliterator<K,V>
+        extends HashMapSpliterator<K,V>
+        implements Spliterator<V> {
+        ValueSpliterator(HashMap<K,V> m, int origin, int fence, int est,
+                         int expectedModCount) {
+            super(m, origin, fence, est, expectedModCount);
+        }
+
+        public ValueSpliterator<K,V> trySplit() {
+            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
+            return (lo >= mid || current != null) ? null :
+                new ValueSpliterator<K,V>(map, lo, index = mid, est >>>= 1,
+                                          expectedModCount);
+        }
+
+        @SuppressWarnings("unchecked")
+        public void forEachRemaining(Consumer<? super V> action) {
+            int i, hi, mc;
+            if (action == null)
+                throw new NullPointerException();
+            HashMap<K,V> m = map;
+            HashMap.Entry<K,V>[] tab = (HashMap.Entry<K,V>[])m.table;
+            if ((hi = fence) < 0) {
+                mc = expectedModCount = m.modCount;
+                hi = fence = tab.length;
+            }
+            else
+                mc = expectedModCount;
+            if (tab.length >= hi && (i = index) >= 0 && i < (index = hi)) {
+                HashMap.Entry<K,V> p = current;
+                do {
+                    if (p == null)
+                        p = tab[i++];
+                    else {
+                        action.accept(p.getValue());
+                        p = p.next;
+                    }
+                } while (p != null || i < hi);
+                if (m.modCount != mc)
+                    throw new ConcurrentModificationException();
+            }
+        }
+
+        @SuppressWarnings("unchecked")
+        public boolean tryAdvance(Consumer<? super V> action) {
+            int hi;
+            if (action == null)
+                throw new NullPointerException();
+            HashMap.Entry<K,V>[] tab = (HashMap.Entry<K,V>[])map.table;
+            if (tab.length >= (hi = getFence()) && index >= 0) {
+                while (current != null || index < hi) {
+                    if (current == null)
+                        current = tab[index++];
+                    else {
+                        V v = current.getValue();
+                        current = current.next;
+                        action.accept(v);
+                        if (map.modCount != expectedModCount)
+                            throw new ConcurrentModificationException();
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+
+        public int characteristics() {
+            return (fence < 0 || est == map.size ? Spliterator.SIZED : 0);
+        }
+    }
+
+    static final class EntrySpliterator<K,V>
+        extends HashMapSpliterator<K,V>
+        implements Spliterator<Map.Entry<K,V>> {
+        EntrySpliterator(HashMap<K,V> m, int origin, int fence, int est,
+                         int expectedModCount) {
+            super(m, origin, fence, est, expectedModCount);
+        }
+
+        public EntrySpliterator<K,V> trySplit() {
+            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
+            return (lo >= mid || current != null) ? null :
+                new EntrySpliterator<K,V>(map, lo, index = mid, est >>>= 1,
+                                          expectedModCount);
+        }
+
+        @SuppressWarnings("unchecked")
+        public void forEachRemaining(Consumer<? super Map.Entry<K,V>> action) {
+            int i, hi, mc;
+            if (action == null)
+                throw new NullPointerException();
+            HashMap<K,V> m = map;
+            HashMap.Entry<K,V>[] tab = (HashMap.Entry<K,V>[])m.table;
+            if ((hi = fence) < 0) {
+                mc = expectedModCount = m.modCount;
+                hi = fence = tab.length;
+            }
+            else
+                mc = expectedModCount;
+            if (tab.length >= hi && (i = index) >= 0 && i < (index = hi)) {
+                HashMap.Entry<K,V> p = current;
+                do {
+                    if (p == null)
+                        p = tab[i++];
+                    else {
+                        action.accept(p);
+                        p = p.next;
+                    }
+                } while (p != null || i < hi);
+                if (m.modCount != mc)
+                    throw new ConcurrentModificationException();
+            }
+        }
+
+        @SuppressWarnings("unchecked")
+        public boolean tryAdvance(Consumer<? super Map.Entry<K,V>> action) {
+            int hi;
+            if (action == null)
+                throw new NullPointerException();
+            HashMap.Entry<K,V>[] tab = (HashMap.Entry<K,V>[])map.table;
+            if (tab.length >= (hi = getFence()) && index >= 0) {
+                while (current != null || index < hi) {
+                    if (current == null)
+                        current = tab[index++];
+                    else {
+                        HashMap.Entry<K,V> e = current;
+                        current = current.next;
+                        action.accept(e);
+                        if (map.modCount != expectedModCount)
+                            throw new ConcurrentModificationException();
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+
+        public int characteristics() {
+            return (fence < 0 || est == map.size ? Spliterator.SIZED : 0) |
+                Spliterator.DISTINCT;
+        }
+    }
 }
--- a/src/share/classes/java/util/HashSet.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/util/HashSet.java	Tue Apr 23 11:13:38 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -311,4 +311,8 @@
             map.put(e, PRESENT);
         }
     }
+
+    public Spliterator<E> spliterator() {
+        return new HashMap.KeySpliterator<E,Object>(map, 0, -1, 0, 0);
+    }
 }
--- a/src/share/classes/java/util/IdentityHashMap.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/util/IdentityHashMap.java	Tue Apr 23 11:13:38 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, 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
@@ -24,8 +24,10 @@
  */
 
 package java.util;
+
 import java.io.*;
 import java.lang.reflect.Array;
+import java.util.function.Consumer;
 
 /**
  * This class implements the <tt>Map</tt> interface with a hash table, using
@@ -162,19 +164,19 @@
     /**
      * The table, resized as necessary. Length MUST always be a power of two.
      */
-    private transient Object[] table;
+    transient Object[] table; // non-private to simplify nested class access
 
     /**
      * The number of key-value mappings contained in this identity hash map.
      *
      * @serial
      */
-    private int size;
+    int size;
 
     /**
      * The number of modifications, to support fast-fail iterators
      */
-    private transient int modCount;
+    transient int modCount;
 
     /**
      * The next size value at which to resize (capacity * load factor).
@@ -184,7 +186,7 @@
     /**
      * Value representing null keys inside tables.
      */
-    private static final Object NULL_KEY = new Object();
+    static final Object NULL_KEY = new Object();
 
     /**
      * Use NULL_KEY for key if it is null.
@@ -196,7 +198,7 @@
     /**
      * Returns internal representation of null key back to caller as null.
      */
-    private static Object unmaskNull(Object key) {
+    static final Object unmaskNull(Object key) {
         return (key == NULL_KEY ? null : key);
     }
 
@@ -1012,7 +1014,7 @@
             return result;
         }
         public Object[] toArray() {
-            return toArray(new Object[size()]);
+            return toArray(new Object[0]);
         }
         @SuppressWarnings("unchecked")
         public <T> T[] toArray(T[] a) {
@@ -1042,6 +1044,10 @@
             }
             return a;
         }
+
+        public Spliterator<K> spliterator() {
+            return new KeySpliterator<>(IdentityHashMap.this, 0, -1, 0, 0);
+        }
     }
 
     /**
@@ -1095,7 +1101,7 @@
             IdentityHashMap.this.clear();
         }
         public Object[] toArray() {
-            return toArray(new Object[size()]);
+            return toArray(new Object[0]);
         }
         @SuppressWarnings("unchecked")
         public <T> T[] toArray(T[] a) {
@@ -1124,6 +1130,10 @@
             }
             return a;
         }
+
+        public Spliterator<V> spliterator() {
+            return new ValueSpliterator<>(IdentityHashMap.this, 0, -1, 0, 0);
+        }
     }
 
     /**
@@ -1211,7 +1221,7 @@
         }
 
         public Object[] toArray() {
-            return toArray(new Object[size()]);
+            return toArray(new Object[0]);
         }
 
         @SuppressWarnings("unchecked")
@@ -1242,6 +1252,10 @@
             }
             return a;
         }
+
+        public Spliterator<Map.Entry<K,V>> spliterator() {
+            return new EntrySpliterator<>(IdentityHashMap.this, 0, -1, 0, 0);
+        }
     }
 
 
@@ -1322,4 +1336,223 @@
         tab[i] = k;
         tab[i + 1] = value;
     }
+
+    /**
+     * Similar form as array-based Spliterators, but skips blank elements,
+     * and guestimates size as decreasing by half per split.
+     */
+    static class IdentityHashMapSpliterator<K,V> {
+        final IdentityHashMap<K,V> map;
+        int index;             // current index, modified on advance/split
+        int fence;             // -1 until first use; then one past last index
+        int est;               // size estimate
+        int expectedModCount;  // initialized when fence set
+
+        IdentityHashMapSpliterator(IdentityHashMap<K,V> map, int origin,
+                                   int fence, int est, int expectedModCount) {
+            this.map = map;
+            this.index = origin;
+            this.fence = fence;
+            this.est = est;
+            this.expectedModCount = expectedModCount;
+        }
+
+        final int getFence() { // initialize fence and size on first use
+            int hi;
+            if ((hi = fence) < 0) {
+                est = map.size;
+                expectedModCount = map.modCount;
+                hi = fence = map.table.length;
+            }
+            return hi;
+        }
+
+        public final long estimateSize() {
+            getFence(); // force init
+            return (long) est;
+        }
+    }
+
+    static final class KeySpliterator<K,V>
+        extends IdentityHashMapSpliterator<K,V>
+        implements Spliterator<K> {
+        KeySpliterator(IdentityHashMap<K,V> map, int origin, int fence, int est,
+                       int expectedModCount) {
+            super(map, origin, fence, est, expectedModCount);
+        }
+
+        public KeySpliterator<K,V> trySplit() {
+            int hi = getFence(), lo = index, mid = ((lo + hi) >>> 1) & ~1;
+            return (lo >= mid) ? null :
+                new KeySpliterator<K,V>(map, lo, index = mid, est >>>= 1,
+                                        expectedModCount);
+        }
+
+        @SuppressWarnings("unchecked")
+        public void forEachRemaining(Consumer<? super K> action) {
+            if (action == null)
+                throw new NullPointerException();
+            int i, hi, mc; Object key;
+            IdentityHashMap<K,V> m; Object[] a;
+            if ((m = map) != null && (a = m.table) != null &&
+                (i = index) >= 0 && (index = hi = getFence()) <= a.length) {
+                for (; i < hi; i += 2) {
+                    if ((key = a[i]) != null)
+                        action.accept((K)unmaskNull(key));
+                }
+                if (m.modCount == expectedModCount)
+                    return;
+            }
+            throw new ConcurrentModificationException();
+        }
+
+        @SuppressWarnings("unchecked")
+        public boolean tryAdvance(Consumer<? super K> action) {
+            if (action == null)
+                throw new NullPointerException();
+            Object[] a = map.table;
+            int hi = getFence();
+            while (index < hi) {
+                Object key = a[index];
+                index += 2;
+                if (key != null) {
+                    action.accept((K)unmaskNull(key));
+                    if (map.modCount != expectedModCount)
+                        throw new ConcurrentModificationException();
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public int characteristics() {
+            return (fence < 0 || est == map.size ? SIZED : 0) | Spliterator.DISTINCT;
+        }
+    }
+
+    static final class ValueSpliterator<K,V>
+        extends IdentityHashMapSpliterator<K,V>
+        implements Spliterator<V> {
+        ValueSpliterator(IdentityHashMap<K,V> m, int origin, int fence, int est,
+                         int expectedModCount) {
+            super(m, origin, fence, est, expectedModCount);
+        }
+
+        public ValueSpliterator<K,V> trySplit() {
+            int hi = getFence(), lo = index, mid = ((lo + hi) >>> 1) & ~1;
+            return (lo >= mid) ? null :
+                new ValueSpliterator<K,V>(map, lo, index = mid, est >>>= 1,
+                                          expectedModCount);
+        }
+
+        public void forEachRemaining(Consumer<? super V> action) {
+            if (action == null)
+                throw new NullPointerException();
+            int i, hi, mc;
+            IdentityHashMap<K,V> m; Object[] a;
+            if ((m = map) != null && (a = m.table) != null &&
+                (i = index) >= 0 && (index = hi = getFence()) <= a.length) {
+                for (; i < hi; i += 2) {
+                    if (a[i] != null) {
+                        @SuppressWarnings("unchecked") V v = (V)a[i+1];
+                        action.accept(v);
+                    }
+                }
+                if (m.modCount == expectedModCount)
+                    return;
+            }
+            throw new ConcurrentModificationException();
+        }
+
+        public boolean tryAdvance(Consumer<? super V> action) {
+            if (action == null)
+                throw new NullPointerException();
+            Object[] a = map.table;
+            int hi = getFence();
+            while (index < hi) {
+                Object key = a[index];
+                @SuppressWarnings("unchecked") V v = (V)a[index+1];
+                index += 2;
+                if (key != null) {
+                    action.accept(v);
+                    if (map.modCount != expectedModCount)
+                        throw new ConcurrentModificationException();
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public int characteristics() {
+            return (fence < 0 || est == map.size ? SIZED : 0);
+        }
+
+    }
+
+    static final class EntrySpliterator<K,V>
+        extends IdentityHashMapSpliterator<K,V>
+        implements Spliterator<Map.Entry<K,V>> {
+        EntrySpliterator(IdentityHashMap<K,V> m, int origin, int fence, int est,
+                         int expectedModCount) {
+            super(m, origin, fence, est, expectedModCount);
+        }
+
+        public EntrySpliterator<K,V> trySplit() {
+            int hi = getFence(), lo = index, mid = ((lo + hi) >>> 1) & ~1;
+            return (lo >= mid) ? null :
+                new EntrySpliterator<K,V>(map, lo, index = mid, est >>>= 1,
+                                          expectedModCount);
+        }
+
+        public void forEachRemaining(Consumer<? super Map.Entry<K, V>> action) {
+            if (action == null)
+                throw new NullPointerException();
+            int i, hi, mc;
+            IdentityHashMap<K,V> m; Object[] a;
+            if ((m = map) != null && (a = m.table) != null &&
+                (i = index) >= 0 && (index = hi = getFence()) <= a.length) {
+                for (; i < hi; i += 2) {
+                    Object key = a[i];
+                    if (key != null) {
+                        @SuppressWarnings("unchecked") K k =
+                            (K)unmaskNull(key);
+                        @SuppressWarnings("unchecked") V v = (V)a[i+1];
+                        action.accept
+                            (new AbstractMap.SimpleImmutableEntry<K,V>(k, v));
+
+                    }
+                }
+                if (m.modCount == expectedModCount)
+                    return;
+            }
+            throw new ConcurrentModificationException();
+        }
+
+        public boolean tryAdvance(Consumer<? super Map.Entry<K,V>> action) {
+            if (action == null)
+                throw new NullPointerException();
+            Object[] a = map.table;
+            int hi = getFence();
+            while (index < hi) {
+                Object key = a[index];
+                @SuppressWarnings("unchecked") V v = (V)a[index+1];
+                index += 2;
+                if (key != null) {
+                    @SuppressWarnings("unchecked") K k =
+                        (K)unmaskNull(key);
+                    action.accept
+                        (new AbstractMap.SimpleImmutableEntry<K,V>(k, v));
+                    if (map.modCount != expectedModCount)
+                        throw new ConcurrentModificationException();
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public int characteristics() {
+            return (fence < 0 || est == map.size ? SIZED : 0) | Spliterator.DISTINCT;
+        }
+    }
+
 }
--- a/src/share/classes/java/util/LinkedHashSet.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/util/LinkedHashSet.java	Tue Apr 23 11:13:38 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, 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
@@ -168,4 +168,18 @@
         super(Math.max(2*c.size(), 11), .75f, true);
         addAll(c);
     }
+
+    /**
+     * Creates a {@code Spliterator}, over the elements in this set, that
+     * reports {@code SIZED}, {@code DISTINCT} and {@code ORDERED}.
+     * Overriding implementations are expected to document if the
+     * {@code Spliterator} reports any additional and relevant characteristic
+     * values.
+     *
+     * @return a {@code Spliterator} over the elements in this set
+     */
+    @Override
+    public Spliterator<E> spliterator() {
+        return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED);
+    }
 }
--- a/src/share/classes/java/util/LinkedList.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/util/LinkedList.java	Tue Apr 23 11:13:38 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -25,6 +25,8 @@
 
 package java.util;
 
+import java.util.function.Consumer;
+
 /**
  * Doubly-linked list implementation of the {@code List} and {@code Deque}
  * interfaces.  Implements all optional list operations, and permits all
@@ -948,6 +950,16 @@
             expectedModCount++;
         }
 
+        public void forEachRemaining(Consumer<? super E> action) {
+            Objects.requireNonNull(action);
+            while (modCount == expectedModCount && nextIndex < size) {
+                action.accept(next.item);
+                next = next.next;
+                nextIndex++;
+            }
+            checkForComodification();
+        }
+
         final void checkForComodification() {
             if (modCount != expectedModCount)
                 throw new ConcurrentModificationException();
@@ -1135,4 +1147,103 @@
         for (int i = 0; i < size; i++)
             linkLast((E)s.readObject());
     }
+
+    public Spliterator<E> spliterator() {
+        return new LLSpliterator<E>(this, -1, 0);
+    }
+
+    /** A customized variant of Spliterators.IteratorSpliterator */
+    static final class LLSpliterator<E> implements Spliterator<E> {
+        static final int BATCH_UNIT = 1 << 10;  // batch array size increment
+        static final int MAX_BATCH = 1 << 25;  // max batch array size;
+        final LinkedList<E> list; // null OK unless traversed
+        Node<E> current;      // current node; null until initialized
+        int est;              // size estimate; -1 until first needed
+        int expectedModCount; // initialized when est set
+        int batch;            // batch size for splits
+
+        LLSpliterator(LinkedList<E> list, int est, int expectedModCount) {
+            this.list = list;
+            this.est = est;
+            this.expectedModCount = expectedModCount;
+        }
+
+        final int getEst() {
+            int s; // force initialization
+            final LinkedList<E> lst;
+            if ((s = est) < 0) {
+                if ((lst = list) == null)
+                    s = est = 0;
+                else {
+                    expectedModCount = lst.modCount;
+                    current = lst.first;
+                    s = est = lst.size;
+                }
+            }
+            return s;
+        }
+
+        public long estimateSize() { return (long) getEst(); }
+
+        public Spliterator<E> trySplit() {
+            Node<E> p;
+            int s = getEst();
+            if (s > 1 && (p = current) != null) {
+                int n = batch + BATCH_UNIT;
+                if (n > s)
+                    n = s;
+                if (n > MAX_BATCH)
+                    n = MAX_BATCH;
+                Object[] a;
+                try {
+                    a = new Object[n];
+                } catch (OutOfMemoryError oome) {
+                    return null;
+                }
+                int j = 0;
+                do { a[j++] = p.item; } while ((p = p.next) != null && j < n);
+                current = p;
+                batch = j;
+                est = s - j;
+                return Spliterators.spliterator(a, 0, j, Spliterator.ORDERED);
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super E> action) {
+            Node<E> p; int n;
+            if (action == null) throw new NullPointerException();
+            if ((n = getEst()) > 0 && (p = current) != null) {
+                current = null;
+                est = 0;
+                do {
+                    E e = p.item;
+                    p = p.next;
+                    action.accept(e);
+                } while (p != null && --n > 0);
+            }
+            if (list.modCount != expectedModCount)
+                throw new ConcurrentModificationException();
+        }
+
+        public boolean tryAdvance(Consumer<? super E> action) {
+            Node<E> p;
+            if (action == null) throw new NullPointerException();
+            if (getEst() > 0 && (p = current) != null) {
+                --est;
+                E e = p.item;
+                current = p.next;
+                action.accept(e);
+                if (list.modCount != expectedModCount)
+                    throw new ConcurrentModificationException();
+                return true;
+            }
+            return false;
+        }
+
+        public int characteristics() {
+            return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
+        }
+    }
+
 }
--- a/src/share/classes/java/util/List.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/util/List.java	Tue Apr 23 11:13:38 2013 +0100
@@ -25,6 +25,8 @@
 
 package java.util;
 
+import java.util.function.UnaryOperator;
+
 /**
  * An ordered collection (also known as a <i>sequence</i>).  The user of this
  * interface has precise control over where in the list each element is
@@ -375,6 +377,64 @@
     boolean retainAll(Collection<?> c);
 
     /**
+     * Replaces each element of this list with the result of applying the
+     * operator to that element.  Errors or runtime exceptions thrown by
+     * the operator are relayed to the caller.
+     *
+     * @implSpec
+     * The default implementation is equivalent to, for this {@code list}:
+     * <pre>
+     * final ListIterator<E> li = list.listIterator();
+     * while (li.hasNext()) {
+     *   li.set(operator.apply(li.next()));
+     * }
+     * </pre>
+     * If the list's list-iterator does not support the {@code set} operation
+     * then an {@code UnsupportedOperationException} will be thrown when
+     * replacing the first element.
+     *
+     * @param operator the operator to apply to each element
+     * @throws UnsupportedOperationException if the {@code set}
+     *         operation is not supported by this list
+     * @throws NullPointerException if the specified operator is null or
+     *         if the element is replaced with a null value and this list
+     *         does not permit null elements
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     * @since 1.8
+     */
+    default void replaceAll(UnaryOperator<E> operator) {
+        Objects.requireNonNull(operator);
+        final ListIterator<E> li = this.listIterator();
+        while (li.hasNext()) {
+            li.set(operator.apply(li.next()));
+        }
+    }
+
+    /**
+     * Sorts this list using the supplied {@code Comparator} to compare elements.
+     *
+     * @implSpec
+     * The default implementation is equivalent to, for this {@code list}:
+     * <pre>Collections.sort(list, c)</pre>
+     *
+     * @param c the {@code Comparator} used to compare list elements.
+     *          A {@code null} value indicates that the elements'
+     *          {@linkplain Comparable natural ordering} should be used
+     * @throws ClassCastException if the list contains elements that are not
+     *         <i>mutually comparable</i> using the specified comparator
+     * @throws UnsupportedOperationException if the list's list-iterator does
+     *         not support the {@code set} operation
+     * @throws IllegalArgumentException
+     *         (<a href="Collection.html#optional-restrictions">optional</a>)
+     *         if the comparator is found to violate the {@link Comparator}
+     *         contract
+     * @since 1.8
+     */
+    default void sort(Comparator<? super E> c) {
+        Collections.sort(this, c);
+    }
+
+    /**
      * Removes all of the elements from this list (optional operation).
      * The list will be empty after this call returns.
      *
--- a/src/share/classes/java/util/PriorityQueue.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/util/PriorityQueue.java	Tue Apr 23 11:13:38 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -25,6 +25,8 @@
 
 package java.util;
 
+import java.util.function.Consumer;
+
 /**
  * An unbounded priority {@linkplain Queue queue} based on a priority heap.
  * The elements of the priority queue are ordered according to their
@@ -56,7 +58,7 @@
  * the priority queue in any particular order. If you need ordered
  * traversal, consider using {@code Arrays.sort(pq.toArray())}.
  *
- * <p> <strong>Note that this implementation is not synchronized.</strong>
+ * <p><strong>Note that this implementation is not synchronized.</strong>
  * Multiple threads should not access a {@code PriorityQueue}
  * instance concurrently if any of the threads modifies the queue.
  * Instead, use the thread-safe {@link
@@ -92,7 +94,7 @@
      * heap and each descendant d of n, n <= d.  The element with the
      * lowest value is in queue[0], assuming the queue is nonempty.
      */
-    private transient Object[] queue;
+    transient Object[] queue; // non-private to simplify nested class access
 
     /**
      * The number of elements in the priority queue.
@@ -109,7 +111,7 @@
      * The number of times this priority queue has been
      * <i>structurally modified</i>.  See AbstractList for gory details.
      */
-    private transient int modCount = 0;
+    transient int modCount = 0; // non-private to simplify nested class access
 
     /**
      * Creates a {@code PriorityQueue} with the default initial
@@ -332,9 +334,7 @@
 
     @SuppressWarnings("unchecked")
     public E peek() {
-        if (size == 0)
-            return null;
-        return (E) queue[0];
+        return (size == 0) ? null : (E) queue[0];
     }
 
     private int indexOf(Object o) {
@@ -431,15 +431,14 @@
      * precise control over the runtime type of the output array, and may,
      * under certain circumstances, be used to save allocation costs.
      *
-     * <p>Suppose <tt>x</tt> is a queue known to contain only strings.
+     * <p>Suppose {@code x} is a queue known to contain only strings.
      * The following code can be used to dump the queue into a newly
-     * allocated array of <tt>String</tt>:
+     * allocated array of {@code String}:
      *
-     * <pre>
-     *     String[] y = x.toArray(new String[0]);</pre>
+     *  <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
      *
-     * Note that <tt>toArray(new Object[0])</tt> is identical in function to
-     * <tt>toArray()</tt>.
+     * Note that {@code toArray(new Object[0])} is identical in function to
+     * {@code toArray()}.
      *
      * @param a the array into which the elements of the queue are to
      *          be stored, if it is big enough; otherwise, a new array of the
@@ -452,6 +451,7 @@
      */
     @SuppressWarnings("unchecked")
     public <T> T[] toArray(T[] a) {
+        final int size = this.size;
         if (a.length < size)
             // Make a new array of a's runtime type, but my contents:
             return (T[]) Arrays.copyOf(queue, size, a.getClass());
@@ -569,15 +569,14 @@
         size = 0;
     }
 
+    @SuppressWarnings("unchecked")
     public E poll() {
         if (size == 0)
             return null;
         int s = --size;
         modCount++;
-        @SuppressWarnings("unchecked")
-            E result = (E) queue[0];
-        @SuppressWarnings("unchecked")
-            E x = (E) queue[s];
+        E result = (E) queue[0];
+        E x = (E) queue[s];
         queue[s] = null;
         if (s != 0)
             siftDown(0, x);
@@ -596,15 +595,15 @@
      * position before i. This fact is used by iterator.remove so as to
      * avoid missing traversing elements.
      */
+    @SuppressWarnings("unchecked")
     private E removeAt(int i) {
-        assert i >= 0 && i < size;
+        // assert i >= 0 && i < size;
         modCount++;
         int s = --size;
         if (s == i) // removed last element
             queue[i] = null;
         else {
-            @SuppressWarnings("unchecked")
-                E moved = (E) queue[s];
+            E moved = (E) queue[s];
             queue[s] = null;
             siftDown(i, moved);
             if (queue[i] == moved) {
@@ -649,12 +648,12 @@
         queue[k] = key;
     }
 
+    @SuppressWarnings("unchecked")
     private void siftUpUsingComparator(int k, E x) {
         while (k > 0) {
             int parent = (k - 1) >>> 1;
-            @SuppressWarnings("unchecked")
-                E e = (E) queue[parent];
-            if (comparator.compare(x, e) >= 0)
+            Object e = queue[parent];
+            if (comparator.compare(x, (E) e) >= 0)
                 break;
             queue[k] = e;
             k = parent;
@@ -738,8 +737,7 @@
     }
 
     /**
-     * Saves the state of the instance to a stream (that
-     * is, serializes it).
+     * Saves this queue to a stream (that is, serializes it).
      *
      * @serialData The length of the array backing the instance is
      *             emitted (int), followed by all of its elements
@@ -747,7 +745,7 @@
      * @param s the stream
      */
     private void writeObject(java.io.ObjectOutputStream s)
-        throws java.io.IOException{
+        throws java.io.IOException {
         // Write out element count, and any hidden stuff
         s.defaultWriteObject();
 
@@ -783,4 +781,99 @@
         // spec has never explained what that might be.
         heapify();
     }
+
+    public final Spliterator<E> spliterator() {
+        return new PriorityQueueSpliterator<E>(this, 0, -1, 0);
+    }
+
+    static final class PriorityQueueSpliterator<E> implements Spliterator<E> {
+        /*
+         * This is very similar to ArrayList Spliterator, except for
+         * extra null checks.
+         */
+        private final PriorityQueue<E> pq;
+        private int index;            // current index, modified on advance/split
+        private int fence;            // -1 until first use
+        private int expectedModCount; // initialized when fence set
+
+        /** Creates new spliterator covering the given range */
+        PriorityQueueSpliterator(PriorityQueue<E> pq, int origin, int fence,
+                             int expectedModCount) {
+            this.pq = pq;
+            this.index = origin;
+            this.fence = fence;
+            this.expectedModCount = expectedModCount;
+        }
+
+        private int getFence() { // initialize fence to size on first use
+            int hi;
+            if ((hi = fence) < 0) {
+                expectedModCount = pq.modCount;
+                hi = fence = pq.size;
+            }
+            return hi;
+        }
+
+        public PriorityQueueSpliterator<E> trySplit() {
+            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
+            return (lo >= mid) ? null :
+                new PriorityQueueSpliterator<E>(pq, lo, index = mid,
+                                                expectedModCount);
+        }
+
+        @SuppressWarnings("unchecked")
+        public void forEachRemaining(Consumer<? super E> action) {
+            int i, hi, mc; // hoist accesses and checks from loop
+            PriorityQueue<E> q; Object[] a;
+            if (action == null)
+                throw new NullPointerException();
+            if ((q = pq) != null && (a = q.queue) != null) {
+                if ((hi = fence) < 0) {
+                    mc = q.modCount;
+                    hi = q.size;
+                }
+                else
+                    mc = expectedModCount;
+                if ((i = index) >= 0 && (index = hi) <= a.length) {
+                    for (E e;; ++i) {
+                        if (i < hi) {
+                            if ((e = (E) a[i]) == null) // must be CME
+                                break;
+                            action.accept(e);
+                        }
+                        else if (q.modCount != mc)
+                            break;
+                        else
+                            return;
+                    }
+                }
+            }
+            throw new ConcurrentModificationException();
+        }
+
+        public boolean tryAdvance(Consumer<? super E> action) {
+            if (action == null)
+                throw new NullPointerException();
+            int hi = getFence(), lo = index;
+            if (lo >= 0 && lo < hi) {
+                index = lo + 1;
+                @SuppressWarnings("unchecked") E e = (E)pq.queue[lo];
+                if (e == null)
+                    throw new ConcurrentModificationException();
+                action.accept(e);
+                if (pq.modCount != expectedModCount)
+                    throw new ConcurrentModificationException();
+                return true;
+            }
+            return false;
+        }
+
+        public long estimateSize() {
+            return (long) (getFence() - index);
+        }
+
+        public int characteristics() {
+            return Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.NONNULL;
+        }
+    }
 }
--- a/src/share/classes/java/util/TreeMap.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/util/TreeMap.java	Tue Apr 23 11:13:38 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, 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
@@ -25,6 +25,8 @@
 
 package java.util;
 
+import java.util.function.Consumer;
+
 /**
  * A Red-Black tree based {@link NavigableMap} implementation.
  * The map is sorted according to the {@linkplain Comparable natural
@@ -971,6 +973,10 @@
         public void clear() {
             TreeMap.this.clear();
         }
+
+        public Spliterator<V> spliterator() {
+            return new ValueSpliterator<K,V>(TreeMap.this, null, null, 0, -1, 0);
+        }
     }
 
     class EntrySet extends AbstractSet<Map.Entry<K,V>> {
@@ -1007,6 +1013,10 @@
         public void clear() {
             TreeMap.this.clear();
         }
+
+        public Spliterator<Map.Entry<K,V>> spliterator() {
+            return new EntrySpliterator<K,V>(TreeMap.this, null, null, 0, -1, 0);
+        }
     }
 
     /*
@@ -1090,6 +1100,10 @@
         public NavigableSet<E> descendingSet() {
             return new KeySet<>(m.descendingMap());
         }
+
+        public Spliterator<E> spliterator() {
+            return keySpliteratorFor(m);
+        }
     }
 
     /**
@@ -1389,6 +1403,8 @@
         /** Returns ascending iterator from the perspective of this submap */
         abstract Iterator<K> keyIterator();
 
+        abstract Spliterator<K> keySpliterator();
+
         /** Returns descending iterator from the perspective of this submap */
         abstract Iterator<K> descendingKeyIterator();
 
@@ -1650,19 +1666,6 @@
             }
         }
 
-        final class SubMapKeyIterator extends SubMapIterator<K> {
-            SubMapKeyIterator(TreeMap.Entry<K,V> first,
-                              TreeMap.Entry<K,V> fence) {
-                super(first, fence);
-            }
-            public K next() {
-                return nextEntry().key;
-            }
-            public void remove() {
-                removeAscending();
-            }
-        }
-
         final class DescendingSubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> {
             DescendingSubMapEntryIterator(TreeMap.Entry<K,V> last,
                                           TreeMap.Entry<K,V> fence) {
@@ -1677,7 +1680,47 @@
             }
         }
 
-        final class DescendingSubMapKeyIterator extends SubMapIterator<K> {
+        // Implement minimal Spliterator as KeySpliterator backup
+        final class SubMapKeyIterator extends SubMapIterator<K>
+            implements Spliterator<K> {
+            SubMapKeyIterator(TreeMap.Entry<K,V> first,
+                              TreeMap.Entry<K,V> fence) {
+                super(first, fence);
+            }
+            public K next() {
+                return nextEntry().key;
+            }
+            public void remove() {
+                removeAscending();
+            }
+            public Spliterator<K> trySplit() {
+                return null;
+            }
+            public void forEachRemaining(Consumer<? super K> action) {
+                while (hasNext())
+                    action.accept(next());
+            }
+            public boolean tryAdvance(Consumer<? super K> action) {
+                if (hasNext()) {
+                    action.accept(next());
+                    return true;
+                }
+                return false;
+            }
+            public long estimateSize() {
+                return Long.MAX_VALUE;
+            }
+            public int characteristics() {
+                return Spliterator.DISTINCT | Spliterator.ORDERED |
+                    Spliterator.SORTED;
+            }
+            public final Comparator<? super K>  getComparator() {
+                return NavigableSubMap.this.comparator();
+            }
+        }
+
+        final class DescendingSubMapKeyIterator extends SubMapIterator<K>
+            implements Spliterator<K> {
             DescendingSubMapKeyIterator(TreeMap.Entry<K,V> last,
                                         TreeMap.Entry<K,V> fence) {
                 super(last, fence);
@@ -1688,6 +1731,26 @@
             public void remove() {
                 removeDescending();
             }
+            public Spliterator<K> trySplit() {
+                return null;
+            }
+            public void forEachRemaining(Consumer<? super K> action) {
+                while (hasNext())
+                    action.accept(next());
+            }
+            public boolean tryAdvance(Consumer<? super K> action) {
+                if (hasNext()) {
+                    action.accept(next());
+                    return true;
+                }
+                return false;
+            }
+            public long estimateSize() {
+                return Long.MAX_VALUE;
+            }
+            public int characteristics() {
+                return Spliterator.DISTINCT | Spliterator.ORDERED;
+            }
         }
     }
 
@@ -1747,6 +1810,10 @@
             return new SubMapKeyIterator(absLowest(), absHighFence());
         }
 
+        Spliterator<K> keySpliterator() {
+            return new SubMapKeyIterator(absLowest(), absHighFence());
+        }
+
         Iterator<K> descendingKeyIterator() {
             return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
         }
@@ -1828,6 +1895,10 @@
             return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
         }
 
+        Spliterator<K> keySpliterator() {
+            return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
+        }
+
         Iterator<K> descendingKeyIterator() {
             return new SubMapKeyIterator(absLowest(), absHighFence());
         }
@@ -2444,4 +2515,407 @@
             level++;
         return level;
     }
+
+    /**
+     * Currently, we support Spliterator-based versions only for the
+     * full map, in either plain of descending form, otherwise relying
+     * on defaults because size estimation for submaps would dominate
+     * costs. The type tests needed to check these for key views are
+     * not very nice but avoid disrupting existing class
+     * structures. Callers must use plain default spliterators if this
+     * returns null.
+     */
+    static <K> Spliterator<K> keySpliteratorFor(NavigableMap<K,?> m) {
+        if (m instanceof TreeMap) {
+            @SuppressWarnings("unchecked") TreeMap<K,Object> t =
+                (TreeMap<K,Object>) m;
+            return t.keySpliterator();
+        }
+        if (m instanceof DescendingSubMap) {
+            @SuppressWarnings("unchecked") DescendingSubMap<K,?> dm =
+                (DescendingSubMap<K,?>) m;
+            TreeMap<K,?> tm = dm.m;
+            if (dm == tm.descendingMap) {
+                @SuppressWarnings("unchecked") TreeMap<K,Object> t =
+                    (TreeMap<K,Object>) tm;
+                return t.descendingKeySpliterator();
+            }
+        }
+        @SuppressWarnings("unchecked") NavigableSubMap<K,?> sm =
+            (NavigableSubMap<K,?>) m;
+        return sm.keySpliterator();
+    }
+
+    final Spliterator<K> keySpliterator() {
+        return new KeySpliterator<K,V>(this, null, null, 0, -1, 0);
+    }
+
+    final Spliterator<K> descendingKeySpliterator() {
+        return new DescendingKeySpliterator<K,V>(this, null, null, 0, -2, 0);
+    }
+
+    /**
+     * Base class for spliterators.  Iteration starts at a given
+     * origin and continues up to but not including a given fence (or
+     * null for end).  At top-level, for ascending cases, the first
+     * split uses the root as left-fence/right-origin. From there,
+     * right-hand splits replace the current fence with its left
+     * child, also serving as origin for the split-off spliterator.
+     * Left-hands are symmetric. Descending versions place the origin
+     * at the end and invert ascending split rules.  This base class
+     * is non-commital about directionality, or whether the top-level
+     * spliterator covers the whole tree. This means that the actual
+     * split mechanics are located in subclasses. Some of the subclass
+     * trySplit methods are identical (except for return types), but
+     * not nicely factorable.
+     *
+     * Currently, subclass versions exist only for the full map
+     * (including descending keys via its descendingMap).  Others are
+     * possible but currently not worthwhile because submaps require
+     * O(n) computations to determine size, which substantially limits
+     * potential speed-ups of using custom Spliterators versus default
+     * mechanics.
+     *
+     * To boostrap initialization, external constructors use
+     * negative size estimates: -1 for ascend, -2 for descend.
+     */
+    static class TreeMapSpliterator<K,V> {
+        final TreeMap<K,V> tree;
+        TreeMap.Entry<K,V> current; // traverser; initially first node in range
+        TreeMap.Entry<K,V> fence;   // one past last, or null
+        int side;                   // 0: top, -1: is a left split, +1: right
+        int est;                    // size estimate (exact only for top-level)
+        int expectedModCount;       // for CME checks
+
+        TreeMapSpliterator(TreeMap<K,V> tree,
+                           TreeMap.Entry<K,V> origin, TreeMap.Entry<K,V> fence,
+                           int side, int est, int expectedModCount) {
+            this.tree = tree;
+            this.current = origin;
+            this.fence = fence;
+            this.side = side;
+            this.est = est;
+            this.expectedModCount = expectedModCount;
+        }
+
+        final int getEstimate() { // force initialization
+            int s; TreeMap<K,V> t;
+            if ((s = est) < 0) {
+                if ((t = tree) != null) {
+                    current = (s == -1) ? t.getFirstEntry() : t.getLastEntry();
+                    s = est = t.size;
+                    expectedModCount = t.modCount;
+                }
+                else
+                    s = est = 0;
+            }
+            return s;
+        }
+
+        public final long estimateSize() {
+            return (long)getEstimate();
+        }
+    }
+
+    static final class KeySpliterator<K,V>
+        extends TreeMapSpliterator<K,V>
+        implements Spliterator<K> {
+        KeySpliterator(TreeMap<K,V> tree,
+                       TreeMap.Entry<K,V> origin, TreeMap.Entry<K,V> fence,
+                       int side, int est, int expectedModCount) {
+            super(tree, origin, fence, side, est, expectedModCount);
+        }
+
+        public KeySpliterator<K,V> trySplit() {
+            if (est < 0)
+                getEstimate(); // force initialization
+            int d = side;
+            TreeMap.Entry<K,V> e = current, f = fence,
+                s = ((e == null || e == f) ? null :      // empty
+                     (d == 0)              ? tree.root : // was top
+                     (d >  0)              ? e.right :   // was right
+                     (d <  0 && f != null) ? f.left :    // was left
+                     null);
+            if (s != null && s != e && s != f &&
+                tree.compare(e.key, s.key) < 0) {        // e not already past s
+                side = 1;
+                return new KeySpliterator<>
+                    (tree, e, current = s, -1, est >>>= 1, expectedModCount);
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super K> action) {
+            if (action == null)
+                throw new NullPointerException();
+            if (est < 0)
+                getEstimate(); // force initialization
+            TreeMap.Entry<K,V> f = fence, e, p, pl;
+            if ((e = current) != null && e != f) {
+                current = f; // exhaust
+                do {
+                    action.accept(e.key);
+                    if ((p = e.right) != null) {
+                        while ((pl = p.left) != null)
+                            p = pl;
+                    }
+                    else {
+                        while ((p = e.parent) != null && e == p.right)
+                            e = p;
+                    }
+                } while ((e = p) != null && e != f);
+                if (tree.modCount != expectedModCount)
+                    throw new ConcurrentModificationException();
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super K> action) {
+            TreeMap.Entry<K,V> e;
+            if (action == null)
+                throw new NullPointerException();
+            if (est < 0)
+                getEstimate(); // force initialization
+            if ((e = current) == null || e == fence)
+                return false;
+            current = successor(e);
+            action.accept(e.key);
+            if (tree.modCount != expectedModCount)
+                throw new ConcurrentModificationException();
+            return true;
+        }
+
+        public int characteristics() {
+            return (side == 0 ? Spliterator.SIZED : 0) |
+                Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED;
+        }
+
+        public final Comparator<? super K>  getComparator() {
+            return tree.comparator;
+        }
+
+    }
+
+    static final class DescendingKeySpliterator<K,V>
+        extends TreeMapSpliterator<K,V>
+        implements Spliterator<K> {
+        DescendingKeySpliterator(TreeMap<K,V> tree,
+                                 TreeMap.Entry<K,V> origin, TreeMap.Entry<K,V> fence,
+                                 int side, int est, int expectedModCount) {
+            super(tree, origin, fence, side, est, expectedModCount);
+        }
+
+        public DescendingKeySpliterator<K,V> trySplit() {
+            if (est < 0)
+                getEstimate(); // force initialization
+            int d = side;
+            TreeMap.Entry<K,V> e = current, f = fence,
+                    s = ((e == null || e == f) ? null :      // empty
+                         (d == 0)              ? tree.root : // was top
+                         (d <  0)              ? e.left :    // was left
+                         (d >  0 && f != null) ? f.right :   // was right
+                         null);
+            if (s != null && s != e && s != f &&
+                tree.compare(e.key, s.key) > 0) {       // e not already past s
+                side = 1;
+                return new DescendingKeySpliterator<>
+                        (tree, e, current = s, -1, est >>>= 1, expectedModCount);
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super K> action) {
+            if (action == null)
+                throw new NullPointerException();
+            if (est < 0)
+                getEstimate(); // force initialization
+            TreeMap.Entry<K,V> f = fence, e, p, pr;
+            if ((e = current) != null && e != f) {
+                current = f; // exhaust
+                do {
+                    action.accept(e.key);
+                    if ((p = e.left) != null) {
+                        while ((pr = p.right) != null)
+                            p = pr;
+                    }
+                    else {
+                        while ((p = e.parent) != null && e == p.left)
+                            e = p;
+                    }
+                } while ((e = p) != null && e != f);
+                if (tree.modCount != expectedModCount)
+                    throw new ConcurrentModificationException();
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super K> action) {
+            TreeMap.Entry<K,V> e;
+            if (action == null)
+                throw new NullPointerException();
+            if (est < 0)
+                getEstimate(); // force initialization
+            if ((e = current) == null || e == fence)
+                return false;
+            current = predecessor(e);
+            action.accept(e.key);
+            if (tree.modCount != expectedModCount)
+                throw new ConcurrentModificationException();
+            return true;
+        }
+
+        public int characteristics() {
+            return (side == 0 ? Spliterator.SIZED : 0) |
+                Spliterator.DISTINCT | Spliterator.ORDERED;
+        }
+    }
+
+    static final class ValueSpliterator<K,V>
+            extends TreeMapSpliterator<K,V>
+            implements Spliterator<V> {
+        ValueSpliterator(TreeMap<K,V> tree,
+                         TreeMap.Entry<K,V> origin, TreeMap.Entry<K,V> fence,
+                         int side, int est, int expectedModCount) {
+            super(tree, origin, fence, side, est, expectedModCount);
+        }
+
+        public ValueSpliterator<K,V> trySplit() {
+            if (est < 0)
+                getEstimate(); // force initialization
+            int d = side;
+            TreeMap.Entry<K,V> e = current, f = fence,
+                    s = ((e == null || e == f) ? null :      // empty
+                         (d == 0)              ? tree.root : // was top
+                         (d >  0)              ? e.right :   // was right
+                         (d <  0 && f != null) ? f.left :    // was left
+                         null);
+            if (s != null && s != e && s != f &&
+                tree.compare(e.key, s.key) < 0) {        // e not already past s
+                side = 1;
+                return new ValueSpliterator<>
+                        (tree, e, current = s, -1, est >>>= 1, expectedModCount);
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super V> action) {
+            if (action == null)
+                throw new NullPointerException();
+            if (est < 0)
+                getEstimate(); // force initialization
+            TreeMap.Entry<K,V> f = fence, e, p, pl;
+            if ((e = current) != null && e != f) {
+                current = f; // exhaust
+                do {
+                    action.accept(e.value);
+                    if ((p = e.right) != null) {
+                        while ((pl = p.left) != null)
+                            p = pl;
+                    }
+                    else {
+                        while ((p = e.parent) != null && e == p.right)
+                            e = p;
+                    }
+                } while ((e = p) != null && e != f);
+                if (tree.modCount != expectedModCount)
+                    throw new ConcurrentModificationException();
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super V> action) {
+            TreeMap.Entry<K,V> e;
+            if (action == null)
+                throw new NullPointerException();
+            if (est < 0)
+                getEstimate(); // force initialization
+            if ((e = current) == null || e == fence)
+                return false;
+            current = successor(e);
+            action.accept(e.value);
+            if (tree.modCount != expectedModCount)
+                throw new ConcurrentModificationException();
+            return true;
+        }
+
+        public int characteristics() {
+            return (side == 0 ? Spliterator.SIZED : 0);
+        }
+    }
+
+    static final class EntrySpliterator<K,V>
+        extends TreeMapSpliterator<K,V>
+        implements Spliterator<Map.Entry<K,V>> {
+        EntrySpliterator(TreeMap<K,V> tree,
+                         TreeMap.Entry<K,V> origin, TreeMap.Entry<K,V> fence,
+                         int side, int est, int expectedModCount) {
+            super(tree, origin, fence, side, est, expectedModCount);
+        }
+
+        public EntrySpliterator<K,V> trySplit() {
+            if (est < 0)
+                getEstimate(); // force initialization
+            int d = side;
+            TreeMap.Entry<K,V> e = current, f = fence,
+                    s = ((e == null || e == f) ? null :      // empty
+                         (d == 0)              ? tree.root : // was top
+                         (d >  0)              ? e.right :   // was right
+                         (d <  0 && f != null) ? f.left :    // was left
+                         null);
+            if (s != null && s != e && s != f &&
+                tree.compare(e.key, s.key) < 0) {        // e not already past s
+                side = 1;
+                return new EntrySpliterator<>
+                        (tree, e, current = s, -1, est >>>= 1, expectedModCount);
+            }
+            return null;
+        }
+
+        public void forEachRemaining(Consumer<? super Map.Entry<K, V>> action) {
+            if (action == null)
+                throw new NullPointerException();
+            if (est < 0)
+                getEstimate(); // force initialization
+            TreeMap.Entry<K,V> f = fence, e, p, pl;
+            if ((e = current) != null && e != f) {
+                current = f; // exhaust
+                do {
+                    action.accept(e);
+                    if ((p = e.right) != null) {
+                        while ((pl = p.left) != null)
+                            p = pl;
+                    }
+                    else {
+                        while ((p = e.parent) != null && e == p.right)
+                            e = p;
+                    }
+                } while ((e = p) != null && e != f);
+                if (tree.modCount != expectedModCount)
+                    throw new ConcurrentModificationException();
+            }
+        }
+
+        public boolean tryAdvance(Consumer<? super Map.Entry<K,V>> action) {
+            TreeMap.Entry<K,V> e;
+            if (action == null)
+                throw new NullPointerException();
+            if (est < 0)
+                getEstimate(); // force initialization
+            if ((e = current) == null || e == fence)
+                return false;
+            current = successor(e);
+            action.accept(e);
+            if (tree.modCount != expectedModCount)
+                throw new ConcurrentModificationException();
+            return true;
+        }
+
+        public int characteristics() {
+            return (side == 0 ? Spliterator.SIZED : 0) |
+                   Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED;
+        }
+
+        @Override
+        public Comparator<? super Map.Entry<K, V>> getComparator() {
+            return tree.comparator != null ?
+                   Comparators.byKey(tree.comparator) : null;
+        }
+    }
 }
--- a/src/share/classes/java/util/TreeSet.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/util/TreeSet.java	Tue Apr 23 11:13:38 2013 +0100
@@ -533,5 +533,9 @@
         tm.readTreeSet(size, s, PRESENT);
     }
 
+    public Spliterator<E> spliterator() {
+        return TreeMap.keySpliteratorFor(m);
+    }
+
     private static final long serialVersionUID = -2479143000061671589L;
 }
--- a/src/share/classes/java/util/Vector.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/util/Vector.java	Tue Apr 23 11:13:38 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2013, 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
@@ -25,6 +25,12 @@
 
 package java.util;
 
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+import java.util.function.UnaryOperator;
+
+import java.util.function.Consumer;
+
 /**
  * The {@code Vector} class implements a growable array of
  * objects. Like an array, it contains components that can be
@@ -1151,6 +1157,28 @@
             lastRet = -1;
         }
 
+        @Override
+        public void forEachRemaining(Consumer<? super E> action) {
+            Objects.requireNonNull(action);
+            synchronized (Vector.this) {
+                final int size = Vector.this.elementCount;
+                int i = cursor;
+                if (i >= size) {
+                    return;
+                }
+                final Object[] elementData = Vector.this.elementData;
+                if (i >= elementData.length) {
+                    throw new ConcurrentModificationException();
+                }
+                while (i != size && modCount == expectedModCount) {
+                    action.accept((E) elementData[i++]);
+                }
+                // update once at end of iteration to reduce heap write traffic
+                lastRet = cursor = i;
+                checkForComodification();
+            }
+        }
+
         final void checkForComodification() {
             if (modCount != expectedModCount)
                 throw new ConcurrentModificationException();
@@ -1209,4 +1237,181 @@
             lastRet = -1;
         }
     }
+
+    @Override
+    public synchronized void forEach(Consumer<? super E> action) {
+        Objects.requireNonNull(action);
+        final int expectedModCount = modCount;
+        @SuppressWarnings("unchecked")
+        final E[] elementData = (E[]) this.elementData;
+        final int elementCount = this.elementCount;
+        for (int i=0; modCount == expectedModCount && i < elementCount; i++) {
+            action.accept(elementData[i]);
+        }
+        if (modCount != expectedModCount) {
+            throw new ConcurrentModificationException();
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public synchronized boolean removeIf(Predicate<? super E> filter) {
+        Objects.requireNonNull(filter);
+        // figure out which elements are to be removed
+        // any exception thrown from the filter predicate at this stage
+        // will leave the collection unmodified
+        int removeCount = 0;
+        final int size = elementCount;
+        final BitSet removeSet = new BitSet(size);
+        final int expectedModCount = modCount;
+        for (int i=0; modCount == expectedModCount && i < size; i++) {
+            @SuppressWarnings("unchecked")
+            final E element = (E) elementData[i];
+            if (filter.test(element)) {
+                removeSet.set(i);
+                removeCount++;
+            }
+        }
+        if (modCount != expectedModCount) {
+            throw new ConcurrentModificationException();
+        }
+
+        // shift surviving elements left over the spaces left by removed elements
+        final boolean anyToRemove = removeCount > 0;
+        if (anyToRemove) {
+            final int newSize = size - removeCount;
+            for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
+                i = removeSet.nextClearBit(i);
+                elementData[j] = elementData[i];
+            }
+            for (int k=newSize; k < size; k++) {
+                elementData[k] = null;  // Let gc do its work
+            }
+            elementCount = newSize;
+            if (modCount != expectedModCount) {
+                throw new ConcurrentModificationException();
+            }
+            modCount++;
+        }
+
+        return anyToRemove;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public synchronized void replaceAll(UnaryOperator<E> operator) {
+        Objects.requireNonNull(operator);
+        final int expectedModCount = modCount;
+        final int size = elementCount;
+        for (int i=0; modCount == expectedModCount && i < size; i++) {
+            elementData[i] = operator.apply((E) elementData[i]);
+        }
+        if (modCount != expectedModCount) {
+            throw new ConcurrentModificationException();
+        }
+        modCount++;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public synchronized void sort(Comparator<? super E> c) {
+        final int expectedModCount = modCount;
+        Arrays.sort((E[]) elementData, 0, elementCount, c);
+        if (modCount != expectedModCount) {
+            throw new ConcurrentModificationException();
+        }
+        modCount++;
+    }
+
+    @Override
+    public Spliterator<E> spliterator() {
+        return new VectorSpliterator<>(this, null, 0, -1, 0);
+    }
+
+    /** Similar to ArrayList Spliterator */
+    static final class VectorSpliterator<E> implements Spliterator<E> {
+        private final Vector<E> list;
+        private Object[] array;
+        private int index; // current index, modified on advance/split
+        private int fence; // -1 until used; then one past last index
+        private int expectedModCount; // initialized when fence set
+
+        /** Create new spliterator covering the given  range */
+        VectorSpliterator(Vector<E> list, Object[] array, int origin, int fence,
+                          int expectedModCount) {
+            this.list = list;
+            this.array = array;
+            this.index = origin;
+            this.fence = fence;
+            this.expectedModCount = expectedModCount;
+        }
+
+        private int getFence() { // initialize on first use
+            int hi;
+            if ((hi = fence) < 0) {
+                synchronized(list) {
+                    array = list.elementData;
+                    expectedModCount = list.modCount;
+                    hi = fence = list.elementCount;
+                }
+            }
+            return hi;
+        }
+
+        public Spliterator<E> trySplit() {
+            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
+            return (lo >= mid) ? null :
+                new VectorSpliterator<E>(list, array, lo, index = mid,
+                                         expectedModCount);
+        }
+
+        @SuppressWarnings("unchecked")
+        public boolean tryAdvance(Consumer<? super E> action) {
+            int i;
+            if (action == null)
+                throw new NullPointerException();
+            if (getFence() > (i = index)) {
+                index = i + 1;
+                action.accept((E)array[i]);
+                if (list.modCount != expectedModCount)
+                    throw new ConcurrentModificationException();
+                return true;
+            }
+            return false;
+        }
+
+        @SuppressWarnings("unchecked")
+        public void forEachRemaining(Consumer<? super E> action) {
+            int i, hi; // hoist accesses and checks from loop
+            Vector<E> lst; Object[] a;
+            if (action == null)
+                throw new NullPointerException();
+            if ((lst = list) != null) {
+                if ((hi = fence) < 0) {
+                    synchronized(lst) {
+                        expectedModCount = lst.modCount;
+                        a = array = lst.elementData;
+                        hi = fence = lst.elementCount;
+                    }
+                }
+                else
+                    a = array;
+                if (a != null && (i = index) >= 0 && (index = hi) <= a.length) {
+                    while (i < hi)
+                        action.accept((E) a[i++]);
+                    if (lst.modCount == expectedModCount)
+                        return;
+                }
+            }
+            throw new ConcurrentModificationException();
+        }
+
+        public long estimateSize() {
+            return (long) (getFence() - index);
+        }
+
+        public int characteristics() {
+            return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
+        }
+    }
 }
--- a/src/share/classes/java/util/WeakHashMap.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/util/WeakHashMap.java	Tue Apr 23 11:13:38 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, 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
@@ -24,8 +24,10 @@
  */
 
 package java.util;
+
 import java.lang.ref.WeakReference;
 import java.lang.ref.ReferenceQueue;
+import java.util.function.Consumer;
 
 
 /**
@@ -898,6 +900,10 @@
         public void clear() {
             WeakHashMap.this.clear();
         }
+
+        public Spliterator<K> spliterator() {
+            return new KeySpliterator<>(WeakHashMap.this, 0, -1, 0, 0);
+        }
     }
 
     /**
@@ -934,6 +940,10 @@
         public void clear() {
             WeakHashMap.this.clear();
         }
+
+        public Spliterator<V> spliterator() {
+            return new ValueSpliterator<>(WeakHashMap.this, 0, -1, 0, 0);
+        }
     }
 
     /**
@@ -994,5 +1004,288 @@
         public <T> T[] toArray(T[] a) {
             return deepCopy().toArray(a);
         }
+
+        public Spliterator<Map.Entry<K,V>> spliterator() {
+            return new EntrySpliterator<>(WeakHashMap.this, 0, -1, 0, 0);
+        }
     }
+
+    /**
+     * Similar form as other hash Spliterators, but skips dead
+     * elements.
+     */
+    static class WeakHashMapSpliterator<K,V> {
+        final WeakHashMap<K,V> map;
+        WeakHashMap.Entry<K,V> current; // current node
+        int index;             // current index, modified on advance/split
+        int fence;             // -1 until first use; then one past last index
+        int est;               // size estimate
+        int expectedModCount;  // for comodification checks
+
+        WeakHashMapSpliterator(WeakHashMap<K,V> m, int origin,
+                               int fence, int est,
+                               int expectedModCount) {
+            this.map = m;
+            this.index = origin;
+            this.fence = fence;
+            this.est = est;
+            this.expectedModCount = expectedModCount;
+        }
+
+        final int getFence() { // initialize fence and size on first use
+            int hi;
+            if ((hi = fence) < 0) {
+                WeakHashMap<K,V> m = map;
+                est = m.size();
+                expectedModCount = m.modCount;
+                hi = fence = m.table.length;
+            }
+            return hi;
+        }
+
+        public final long estimateSize() {
+            getFence(); // force init
+            return (long) est;
+        }
+    }
+
+    static final class KeySpliterator<K,V>
+        extends WeakHashMapSpliterator<K,V>
+        implements Spliterator<K> {
+        KeySpliterator(WeakHashMap<K,V> m, int origin, int fence, int est,
+                       int expectedModCount) {
+            super(m, origin, fence, est, expectedModCount);
+        }
+
+        public KeySpliterator<K,V> trySplit() {
+            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
+            return (lo >= mid) ? null :
+                new KeySpliterator<K,V>(map, lo, index = mid, est >>>= 1,
+                                        expectedModCount);
+        }
+
+        public void forEachRemaining(Consumer<? super K> action) {
+            int i, hi, mc;
+            if (action == null)
+                throw new NullPointerException();
+            WeakHashMap<K,V> m = map;
+            WeakHashMap.Entry<K,V>[] tab = m.table;
+            if ((hi = fence) < 0) {
+                mc = expectedModCount = m.modCount;
+                hi = fence = tab.length;
+            }
+            else
+                mc = expectedModCount;
+            if (tab.length >= hi && (i = index) >= 0 && i < hi) {
+                index = hi;
+                WeakHashMap.Entry<K,V> p = current;
+                do {
+                    if (p == null)
+                        p = tab[i++];
+                    else {
+                        Object x = p.get();
+                        p = p.next;
+                        if (x != null) {
+                            @SuppressWarnings("unchecked") K k =
+                                (K) WeakHashMap.unmaskNull(x);
+                            action.accept(k);
+                        }
+                    }
+                } while (p != null || i < hi);
+            }
+            if (m.modCount != mc)
+                throw new ConcurrentModificationException();
+        }
+
+        public boolean tryAdvance(Consumer<? super K> action) {
+            int hi;
+            if (action == null)
+                throw new NullPointerException();
+            WeakHashMap.Entry<K,V>[] tab = map.table;
+            if (tab.length >= (hi = getFence()) && index >= 0) {
+                while (current != null || index < hi) {
+                    if (current == null)
+                        current = tab[index++];
+                    else {
+                        Object x = current.get();
+                        current = current.next;
+                        if (x != null) {
+                            @SuppressWarnings("unchecked") K k =
+                                (K) WeakHashMap.unmaskNull(x);
+                            action.accept(k);
+                            if (map.modCount != expectedModCount)
+                                throw new ConcurrentModificationException();
+                            return true;
+                        }
+                    }
+                }
+            }
+            return false;
+        }
+
+        public int characteristics() {
+            return Spliterator.DISTINCT;
+        }
+    }
+
+    static final class ValueSpliterator<K,V>
+        extends WeakHashMapSpliterator<K,V>
+        implements Spliterator<V> {
+        ValueSpliterator(WeakHashMap<K,V> m, int origin, int fence, int est,
+                         int expectedModCount) {
+            super(m, origin, fence, est, expectedModCount);
+        }
+
+        public ValueSpliterator<K,V> trySplit() {
+            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
+            return (lo >= mid) ? null :
+                new ValueSpliterator<K,V>(map, lo, index = mid, est >>>= 1,
+                                          expectedModCount);
+        }
+
+        public void forEachRemaining(Consumer<? super V> action) {
+            int i, hi, mc;
+            if (action == null)
+                throw new NullPointerException();
+            WeakHashMap<K,V> m = map;
+            WeakHashMap.Entry<K,V>[] tab = m.table;
+            if ((hi = fence) < 0) {
+                mc = expectedModCount = m.modCount;
+                hi = fence = tab.length;
+            }
+            else
+                mc = expectedModCount;
+            if (tab.length >= hi && (i = index) >= 0 && i < hi) {
+                index = hi;
+                WeakHashMap.Entry<K,V> p = current;
+                do {
+                    if (p == null)
+                        p = tab[i++];
+                    else {
+                        Object x = p.get();
+                        V v = p.value;
+                        p = p.next;
+                        if (x != null)
+                            action.accept(v);
+                    }
+                } while (p != null || i < hi);
+            }
+            if (m.modCount != mc)
+                throw new ConcurrentModificationException();
+        }
+
+        public boolean tryAdvance(Consumer<? super V> action) {
+            int hi;
+            if (action == null)
+                throw new NullPointerException();
+            WeakHashMap.Entry<K,V>[] tab = map.table;
+            if (tab.length >= (hi = getFence()) && index >= 0) {
+                while (current != null || index < hi) {
+                    if (current == null)
+                        current = tab[index++];
+                    else {
+                        Object x = current.get();
+                        V v = current.value;
+                        current = current.next;
+                        if (x != null) {
+                            action.accept(v);
+                            if (map.modCount != expectedModCount)
+                                throw new ConcurrentModificationException();
+                            return true;
+                        }
+                    }
+                }
+            }
+            return false;
+        }
+
+        public int characteristics() {
+            return 0;
+        }
+    }
+
+    static final class EntrySpliterator<K,V>
+        extends WeakHashMapSpliterator<K,V>
+        implements Spliterator<Map.Entry<K,V>> {
+        EntrySpliterator(WeakHashMap<K,V> m, int origin, int fence, int est,
+                       int expectedModCount) {
+            super(m, origin, fence, est, expectedModCount);
+        }
+
+        public EntrySpliterator<K,V> trySplit() {
+            int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
+            return (lo >= mid) ? null :
+                new EntrySpliterator<K,V>(map, lo, index = mid, est >>>= 1,
+                                          expectedModCount);
+        }
+
+
+        public void forEachRemaining(Consumer<? super Map.Entry<K, V>> action) {
+            int i, hi, mc;
+            if (action == null)
+                throw new NullPointerException();
+            WeakHashMap<K,V> m = map;
+            WeakHashMap.Entry<K,V>[] tab = m.table;
+            if ((hi = fence) < 0) {
+                mc = expectedModCount = m.modCount;
+                hi = fence = tab.length;
+            }
+            else
+                mc = expectedModCount;
+            if (tab.length >= hi && (i = index) >= 0 && i < hi) {
+                index = hi;
+                WeakHashMap.Entry<K,V> p = current;
+                do {
+                    if (p == null)
+                        p = tab[i++];
+                    else {
+                        Object x = p.get();
+                        V v = p.value;
+                        p = p.next;
+                        if (x != null) {
+                            @SuppressWarnings("unchecked") K k =
+                                (K) WeakHashMap.unmaskNull(x);
+                            action.accept
+                                (new AbstractMap.SimpleImmutableEntry<K,V>(k, v));
+                        }
+                    }
+                } while (p != null || i < hi);
+            }
+            if (m.modCount != mc)
+                throw new ConcurrentModificationException();
+        }
+
+        public boolean tryAdvance(Consumer<? super Map.Entry<K,V>> action) {
+            int hi;
+            if (action == null)
+                throw new NullPointerException();
+            WeakHashMap.Entry<K,V>[] tab = map.table;
+            if (tab.length >= (hi = getFence()) && index >= 0) {
+                while (current != null || index < hi) {
+                    if (current == null)
+                        current = tab[index++];
+                    else {
+                        Object x = current.get();
+                        V v = current.value;
+                        current = current.next;
+                        if (x != null) {
+                            @SuppressWarnings("unchecked") K k =
+                                (K) WeakHashMap.unmaskNull(x);
+                            action.accept
+                                (new AbstractMap.SimpleImmutableEntry<K,V>(k, v));
+                            if (map.modCount != expectedModCount)
+                                throw new ConcurrentModificationException();
+                            return true;
+                        }
+                    }
+                }
+            }
+            return false;
+        }
+
+        public int characteristics() {
+            return Spliterator.DISTINCT;
+        }
+    }
+
 }
--- a/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java	Tue Apr 23 11:13:38 2013 +0100
@@ -36,6 +36,9 @@
 package java.util.concurrent;
 import java.util.*;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+import java.util.function.UnaryOperator;
 
 /**
  * A thread-safe variant of {@link java.util.ArrayList} in which all mutative
@@ -1260,9 +1263,58 @@
             }
         }
 
+        @Override
+        public void forEach(Consumer<? super E> action) {
+            @SuppressWarnings("unchecked")
+            final E[] elements = (E[]) l.getArray();
+            checkForComodification();
+            l.forEach(action, elements, offset, offset + size);
+        }
+
+        @Override
+        public void sort(Comparator<? super E> c) {
+            final ReentrantLock lock = l.lock;
+            lock.lock();
+            try {
+                checkForComodification();
+                l.sort(c, offset, offset + size);
+                expectedArray = l.getArray();
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        @Override
+        public boolean removeIf(Predicate<? super E> filter) {
+            Objects.requireNonNull(filter);
+            final ReentrantLock lock = l.lock;
+            lock.lock();
+            try {
+                checkForComodification();
+                final int removeCount =
+                        l.removeIf(filter, offset, offset + size);
+                expectedArray = l.getArray();
+                size -= removeCount;
+                return removeCount > 0;
+            } finally {
+                lock.unlock();
+            }
+        }
+
+        @Override
+        public void replaceAll(UnaryOperator<E> operator) {
+            final ReentrantLock lock = l.lock;
+            lock.lock();
+            try {
+                checkForComodification();
+                l.replaceAll(operator, offset, offset + size);
+                expectedArray = l.getArray();
+            } finally {
+                lock.unlock();
+            }
+        }
     }
 
-
     private static class COWSubListIterator<E> implements ListIterator<E> {
         private final ListIterator<E> it;
         private final int offset;
@@ -1333,4 +1385,139 @@
             throw new Error(e);
         }
     }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public void forEach(Consumer<? super E> action) {
+        forEach(action, (E[]) getArray(), 0, size());
+    }
+
+    private void forEach(Consumer<? super E> action,
+                         final E[] elements,
+                         final int from, final int to) {
+        Objects.requireNonNull(action);
+        for (int i = from; i < to; i++) {
+            action.accept(elements[i]);
+        }
+    }
+
+    @Override
+    public void sort(Comparator<? super E> c) {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            sort(c, 0, size());
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    // must be called with this.lock held
+    @SuppressWarnings("unchecked")
+    private void sort(Comparator<? super E> c, final int from, final int to) {
+        final E[] elements = (E[]) getArray();
+        final E[] newElements = Arrays.copyOf(elements, elements.length);
+        // only elements [from, to) are sorted
+        Arrays.sort(newElements, from, to, c);
+        setArray(newElements);
+    }
+
+    @Override
+    public boolean removeIf(Predicate<? super E> filter) {
+        Objects.requireNonNull(filter);
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            return removeIf(filter, 0, size()) > 0;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    // must be called with this.lock held
+    private int removeIf(Predicate<? super E> filter, final int from, final int to) {
+        Objects.requireNonNull(filter);
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            @SuppressWarnings("unchecked")
+            final E[] elements = (E[]) getArray();
+
+            // figure out which elements are to be removed
+            // any exception thrown from the filter predicate at this stage
+            // will leave the collection unmodified
+            int removeCount = 0;
+            final int range = to - from;
+            final BitSet removeSet = new BitSet(range);
+            for (int i = 0; i < range; i++) {
+                final E element = elements[from + i];
+                if (filter.test(element)) {
+                    // removeSet is zero-based to keep its size small
+                    removeSet.set(i);
+                    removeCount++;
+                }
+            }
+
+            // copy surviving elements into a new array
+            if (removeCount > 0) {
+                final int newSize = elements.length - removeCount;
+                final int newRange = newSize - from;
+                @SuppressWarnings("unchecked")
+                final E[] newElements = (E[]) new Object[newSize];
+                // copy elements before [from, to) unmodified
+                for (int i = 0; i < from; i++) {
+                    newElements[i] = elements[i];
+                }
+                // elements [from, to) are subject to removal
+                int j = 0;
+                for (int i = 0; (i < range) && (j < newRange); i++) {
+                    i = removeSet.nextClearBit(i);
+                    if (i >= range) {
+                        break;
+                    }
+                    newElements[from + (j++)] = elements[from + i];
+                }
+                // copy any remaining elements beyond [from, to)
+                j += from;
+                for (int i = to; (i < elements.length) && (j < newSize); i++) {
+                    newElements[j++] = elements[i];
+                }
+                setArray(newElements);
+            }
+
+            return removeCount;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    @Override
+    public void replaceAll(UnaryOperator<E> operator) {
+        Objects.requireNonNull(operator);
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            replaceAll(operator, 0, size());
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    // must be called with this.lock held
+    @SuppressWarnings("unchecked")
+    private void replaceAll(UnaryOperator<E> operator, final int from, final int to) {
+        final E[] elements = (E[]) getArray();
+        final E[] newElements = (E[]) new Object[elements.length];
+        for (int i = 0; i < from; i++) {
+            newElements[i] = elements[i];
+        }
+        // the operator is only applied to elements [from, to)
+        for (int i = from; i < to; i++) {
+            newElements[i] = operator.apply(elements[i]);
+        }
+        for (int i = to; i < elements.length; i++) {
+            newElements[i] = elements[i];
+        }
+        setArray(newElements);
+    }
 }
--- a/src/share/classes/java/util/logging/LogManager.java	Wed Apr 17 15:04:59 2013 -0700
+++ b/src/share/classes/java/util/logging/LogManager.java	Tue Apr 23 11:13:38 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, 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
@@ -35,10 +35,8 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.beans.PropertyChangeListener;
-import java.net.URL;
 import sun.misc.JavaAWTAccess;
 import sun.misc.SharedSecrets;
-import sun.security.action.GetPropertyAction;
 
 /**
  * There is a single global LogManager object that is used to
@@ -148,7 +146,6 @@
     // The global LogManager object
     private static LogManager manager;
 
-    private final static Handler[] emptyHandlers = { };
     private Properties props = new Properties();
     private final static Level defaultLevel = Level.INFO;
 
@@ -555,14 +552,10 @@
             if (name == null) {
                 throw new NullPointerException();
             }
-
-            // cleanup some Loggers that have been GC'ed
-            manager.drainLoggerRefQueueBounded();
-
             LoggerWeakRef ref = namedLoggers.get(name);
             if (ref != null) {
                 if (ref.get() == null) {
-                    // It's possible that the Logger was GC'ed after the
+                    // It's possible that the Logger was GC'ed after a
                     // drainLoggerRefQueueBounded() call above so allow
                     // a new one to be registered.
                     removeLogger(name);
@@ -614,6 +607,8 @@
             return true;
         }
 
+        // note: all calls to removeLogger are synchronized on LogManager's
+        // intrinsic lock
         void removeLogger(String name) {
             namedLoggers.remove(name);
         }
@@ -896,6 +891,7 @@
         if (name == null) {
             throw new NullPointerException();
         }
+        drainLoggerRefQueueBounded();
         LoggerContext cx = getUserContext();
         if (cx.addLocalLogger(logger)) {
             // Do we have a per logger handler too?
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/util/stream/AbstractShortCircuitTask.java	Tue Apr 23 11:13:38 2013 +0100
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2012, 2013, 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;
+
+import java.util.Spliterator;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Abstract class for fork-join tasks used to implement short-circuiting
+ * stream ops, which can produce a result without processing all elements of the
+ * stream.
+ *
+ * @param <P_IN> type of input elements to the pipeline
+ * @param <P_OUT> type of output elements from the pipeline
+ * @param <R> type of intermediate result, may be different from operation
+ *        result type
+ * @param <K> type of child and sibling tasks
+ * @since 1.8
+ */
+abstract class AbstractShortCircuitTask<P_IN, P_OUT, R,
+                                        K extends AbstractShortCircuitTask<P_IN, P_OUT, R, K>>
+        extends AbstractTask<P_IN, P_OUT, R, K> {
+    /**
+     * The result for this computation; this is shared among all tasks and set
+     * exactly once
+     */
+    protected final AtomicReference<R> sharedResult;
+
+    /**
+     * Indicates whether this task has been canceled.  Tasks may cancel other
+     * tasks in the computation under various conditions, such as in a
+     * find-first operation, a task that finds a value will cancel all tasks
+     * that are later in the encounter order.
+     */
+    protected volatile boolean canceled;
+
+    /**
+     * Constructor for root tasks.
+     *
+     * @param helper the {@code PipelineHelper} describing the stream pipeline
+     *               up to this operation
+     * @param spliterator the {@code Spliterator} describing the source for this
+     *                    pipeline
+     */
+    protected AbstractShortCircuitTask(PipelineHelper<P_OUT> helper,
+                                       Spliterator<P_IN> spliterator) {
+        super(helper, spliterator);
+        sharedResult = new AtomicReference<>(null);
+    }
+
+    /**
+     * Constructor for non-root nodes.
+     *
+     * @param parent parent task in the computation tree
+     * @param spliterator the {@code Spliterator} for the portion of the
+     *                    computation tree described by this task
+     */
+    protected AbstractShortCircuitTask(K parent,
+                                       Spliterator<P_IN> spliterator) {
+        super(parent, spliterator);
+        sharedResult = parent.sharedResult;
+    }
+
+    /**
+     * Returns the value indicating the computation completed with no task
+     * finding a short-circuitable result.  For example, for a "find" operation,
+     * this might be null or an empty {@code Optional}.
+     *
+     * @return the result to return when no task finds a result
+     */
+    protected abstract R getEmptyResult();
+
+    @Override
+    protected boolean canCompute() {
+        // Have we already found an answer?
+        if (sharedResult.get() != null) {
+            tryComplete();
+            return false;
+        } else if (taskCanceled()) {
+            setLocalResult(getEmptyResult());
+            tryComplete();
+            return false;
+        }
+        else {
+            return true;
+        }
+    }
+
+    /**
+     * Declares that a globally valid result has been found.  If another task has
+     * not already found the answer, the result is installed in
+     * {@code sharedResult}.  The {@code compute()} method will check
+     * {@code sharedResult} before proceeding with computation, so this causes
+     * the computation to terminate early.
+     *
+     * @param result the result found
+     */
+    protected void shortCircuit(R result) {
+        if (result != null)
+            sharedResult.compareAndSet(null, result);
+    }
+
+    /**
+     * Sets a local result for this task.  If this task is the root, set the
+     * shared result instead (if not already set).
+     *
+     * @param localResult The result to set for this task
+     */
+    @Override
+    protected void setLocalResult(R localResult) {
+        if (isRoot()) {
+            if (localResult != null)
+                sharedResult.compareAndSet(null, localResult);
+        }
+        else
+            super.setLocalResult(localResult);
+    }
+
+    /**
+     * Retrieves the local result for this task
+     */
+    @Override
+    public R getRawResult() {
+        return getLocalResult();
+    }
+
+    /**
+     * Retrieves the local result for this task.  If this task is the root,
+     * retrieves the shared result instead.
+     */
+    @Override
+    public R getLocalResult() {
+        if (isRoot()) {
+            R answer = sharedResult.get();
+            return (answer == null) ? getEmptyResult() : answer;
+        }
+        else
+            return super.getLocalResult();
+    }
+
+    /**
+     * Mark this task as canceled
+     */
+    protected void cancel() {
+        canceled = true;
+    }
+
+    /**
+     * Queries whether this task is canceled.  A task is considered canceled if
+     * it or any of its parents have been canceled.
+     *
+     * @return {@code true} if this task or any parent is canceled.
+     */
+    protected boolean taskCanceled() {
+        boolean cancel = canceled;
+        if (!cancel) {
+            for (K parent = getParent(); !cancel && parent != null; parent = parent.getParent())
+                cancel = parent.canceled;
+        }
+
+        return cancel;
+    }
+
+    /**
+     * Cancels all tasks which succeed this one in the encounter order.  This
+     * includes canceling all the current task's right sibling, as well as the
+     * later right siblings of all its parents.
+     */
+    protected void cancelLaterNodes() {
+        // Go up the tree, cancel right siblings of this node and all parents
+        for (K parent = getParent(), node = (K) this; parent != null;
+             node = parent, parent = parent.getParent()) {
+            // If node is a left child of parent, then has a right sibling
+            if (parent.leftChild == node) {
+                K rightSibling = parent.rightChild;
+                if (!rightSibling.canceled)
+                    rightSibling.cancel();
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/util/stream/AbstractTask.java	Tue Apr 23 11:13:38 2013 +0100
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2012, 2013, 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;
+
+import java.util.Spliterator;
+import java.util.concurrent.CountedCompleter;
+import java.util.concurrent.ForkJoinPool;
+
+/**
+ * Abstract base class for most fork-join tasks used to implement stream ops.
+ * Manages splitting logic, tracking of child tasks, and intermediate results.
+ * Each task is associated with a {@link Spliterator} that describes the portion
+ * of the input associated with the subtree rooted at this task.
+ * Tasks may be leaf nodes (which will traverse the elements of
+ * the {@code Spliterator}) or internal nodes (which split the
+ * {@code Spliterator} into multiple child tasks).
+ *
+ * @implNote
+ * <p>This class is based on {@link CountedCompleter}, a form of fork-join task
+ * where each task has a semaphore-like count of uncompleted children, and the
+ * task is implicitly completed and notified when its last child completes.
+ * Internal node tasks will likely override the {@code onCompletion} method from
+ * {@code CountedCompleter} to merge the results from child tasks into the
+ * current task's result.
+ *
+ * <p>Splitting and setting up the child task links is done by {@code compute()}
+ * for internal nodes.  At {@code compute()} time for leaf nodes, it is
+ * guaranteed that the parent's child-related fields (including sibling links
+ * for the parent's children) will be set up for all children.
+ *
+ * <p>For example, a task that performs a reduce would override {@code doLeaf()}
+ * to perform a reduction on that leaf node's chunk using the
+ * {@code Spliterator}, and override {@code onCompletion()} to merge the results
+ * of the child tasks for internal nodes:
+ *
+ * <pre>{@code
+ *     protected S doLeaf() {
+ *         spliterator.forEach(...);
+ *         return localReductionResult;
+ *     }
+ *
+ *     public void onCompletion(CountedCompleter caller) {
+ *         if (!isLeaf()) {
+ *             ReduceTask<P_IN, P_OUT, T, R> child = children;
+ *             R result = child.getLocalResult();
+ *             child = child.nextSibling;
+ *             for (; child != null; child = child.nextSibling)
+ *                 result = combine(result, child.getLocalResult());
+ *             setLocalResult(result);
+ *         }
+ *     }
+ * }</pre>
+ *
+ * @param <P_IN> Type of elements input to the pipeline
+ * @param <P_OUT> Type of elements output from the pipeline
+ * @param <R> Type of intermediate result, which may be different from operation
+ *        result type
+ * @param <K> Type of parent, child and sibling tasks
+ * @since 1.8
+ */
+abstract class AbstractTask<P_IN, P_OUT, R,
+                            K extends AbstractTask<P_IN, P_OUT, R, K>>
+        extends CountedCompleter<R> {
+
+    /**
+     * Default target factor of leaf tasks for parallel decomposition.
+     * To allow load balancing, we over-partition, currently to approximately
+     * four tasks per processor, which enables others to help out
+     * if leaf tasks are uneven or some processors are otherwise busy.
+     */
+    static final int LEAF_TARGET = ForkJoinPool.getCommonPoolParallelism() << 2;
+
+    /** The pipeline helper, common to all tasks in a computation */
+    protected final PipelineHelper<P_OUT> helper;
+
+    /**
+     * The spliterator for the portion of the input associated with the subtree
+     * rooted at this task
+     */
+    protected Spliterator<P_IN> spliterator;
+
+    /** Target leaf size, common to all tasks in a computation */
+    protected final long targetSize;
+
+    /**
+     * The left child.
+     * null if no children
+     * if non-null rightChild is non-null
+     */
+    protected K leftChild;
+
+    /**
+     * The right child.
+     * null if no children
+     * if non-null leftChild is non-null
+     */
+    protected K rightChild;
+
+    /** The result of this node, if completed */
+    private R localResult;
+
+    /**
+     * Constructor for root nodes.
+     *
+     * @param helper The {@code PipelineHelper} describing the stream pipeline
+     *               up to this operation
+     * @param spliterator The {@code Spliterator} describing the source for this
+     *                    pipeline
+     */
+    protected AbstractTask(PipelineHelper<P_OUT> helper,
+                           Spliterator<P_IN> spliterator) {
+        super(null);
+        this.helper = helper;
+        this.spliterator = spliterator;
+        this.targetSize = suggestTargetSize(spliterator.estimateSize());
+    }
+
+    /**
+     * Constructor for non-root nodes.
+     *
+     * @param parent this node's parent task
+     * @param spliterator {@code Spliterator} describing the subtree rooted at
+     *        this node, obtained by splitting the parent {@code Spliterator}
+     */
+    protected AbstractTask(K parent,
+                           Spliterator<P_IN> spliterator) {
+        super(parent);
+        this.spliterator = spliterator;
+        this.helper = parent.helper;
+        this.targetSize = parent.targetSize;
+    }
+
+    /**
+     * Constructs a new node of type T whose parent is the receiver; must call
+     * the AbstractTask(T, Spliterator) constructor with the receiver and the
+     * provided Spliterator.
+     *
+     * @param spliterator {@code Spliterator} describing the subtree rooted at
+     *        this node, obtained by splitting the parent {@code Spliterator}
+     * @return newly constructed child node
+     */
+    protected abstract K makeChild(Spliterator<P_IN> spliterator);
+
+    /**
+     * Computes the result associated with a leaf node.  Will be called by
+     * {@code compute()} and the result passed to @{code setLocalResult()}
+     *
+     * @return the computed result of a leaf node
+     */
+    protected abstract R doLeaf();
+
+    /**
+     * Returns a suggested target leaf size based on the initial size estimate.
+     *
+     * @return suggested target leaf size
+     */
+    public static long suggestTargetSize(long sizeEstimate) {
+        long est = sizeEstimate / LEAF_TARGET;
+        return est > 0L ? est : 1L;
+    }
+
+    /**
+     * Returns a suggestion whether it is advisable to split the provided
+     * spliterator based on target size and other considerations, such as pool
+     * state.
+      *
+     * @return {@code true} if a split is advised otherwise {@code false}
+     */
+    public static boolean suggestSplit(Spliterator spliterator,
+                                       long targetSize) {
+        long remaining = spliterator.estimateSize();
+        return (remaining > targetSize);
+        // @@@ May additionally want to fold in pool characteristics such as surplus task count
+    }
+
+    /**
+     * Returns a suggestion whether it is adviseable to split this task based on
+     * target size and other considerations.
+      *
+     *  @return {@code true} if a split is advised otherwise {@code false}
+     */
+    public boolean suggestSplit() {
+        return suggestSplit(spliterator, targetSize);
+    }
+
+    /**
+     * Returns the local result, if any. Subclasses should use
+     * {@link #setLocalResult(Object)} and {@link #getLocalResult()} to manage
+     * results.  This returns the local result so that calls from within the
+     * fork-join framework will return the correct result.
+     *
+     * @return local result for this node previously stored with
+     * {@link #setLocalResult}
+     */
+    @Override
+    public R getRawResult() {
+        return localResult;
+    }
+
+    /**
+     * Does nothing; instead, subclasses should use
+     * {@link #setLocalResult(Object)}} to manage results.
+     *
+     * @param result must be null, or an exception is thrown (this is a safety
+     *        tripwire to detect when {@code setRawResult()} is being used
+     *        instead of {@code setLocalResult()}
+     */
+    @Override
+    protected void setRawResult(R result) {
+        if (result != null)
+            throw new IllegalStateException();
+    }
+
+    /**
+     * Retrieves a result previously stored with {@link #setLocalResult}
+     *
+     * @return local result for this node previously stored with
+     * {@link #setLocalResult}
+     */
+    protected R getLocalResult() {
+        return localResult;
+    }
+
+    /**
+     * Associates the result with the task, can be retrieved with
+     * {@link #getLocalResult}
+     *
+     * @param localResult local result for this node
+     */
+    protected void setLocalResult(R localResult) {
+        this.localResult = localResult;
+    }
+
+    /**
+     * Indicates whether this task is a leaf node.  (Only valid after
+     * {@link #compute} has been called on this node).  If the node is not a
+     * leaf node, then children will be non-null and numChildren will be
+     * positive.
+     *
+     * @return {@code true} if this task is a leaf node
+     */
+    protected boolean isLeaf() {
+        return leftChild == null;
+    }
+
+    /**
+     * Indicates whether this task is the root node
+     *
+     * @return {@code true} if this task is the root node.
+     */
+    protected boolean isRoot() {
+        return getParent() == null;
+    }
+
+    /**
+     * Returns the parent of this task, or null if this task is the root
+     *
+     * @return the parent of this task, or null if this task is the root
+     */
+    @SuppressWarnings("unchecked")
+    protected K getParent() {
+        return (K) getCompleter();
+    }
+
+    /**
+     * Decides whether or not to split a task further or compute it directly. If
+     * computing directly, call {@code doLeaf} and pass the result to
+     * {@code setRawResult}.  If splitting, set up the child-related fields,
+     * create the child tasks, fork the leftmost (prefix) child tasks, and
+     * compute the rightmost (remaining) child tasks.
+     *
+     * <p>
+     * Computing will continue for rightmost tasks while a task can be computed
+     * as determined by {@link #canCompute()} and that task should and can be
+     * split into left and right tasks.
+     *
+     * <p>
+     * The rightmost tasks are computed in a loop rather than recursively to
+     * avoid potential stack overflows when computing with a right-balanced
+     * tree, such as that produced when splitting with a {@link Spliterator}
+     * created from an {@link java.util.Iterator}.
+     */
+    @Override
+    public final void compute() {
+        @SuppressWarnings("unchecked")
+        K task = (K) this;
+        while (task.canCompute()) {
+            Spliterator<P_IN> split;
+            if (!task.suggestSplit() || (split = task.spliterator.trySplit()) == null) {
+                task.setLocalResult(task.doLeaf());
+                task.tryComplete();
+                return;
+            }
+            else {
+                K l = task.leftChild = task.makeChild(split);
+                K r = task.rightChild = task.makeChild(task.spliterator);
+                task.setPendingCount(1);
+                l.fork();
+                task = r;
+            }
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @implNote
+     * Clears spliterator and children fields.  Overriders MUST call
+     * {@code super.onCompletion} as the last thing they do if they want these
+     * cleared.
+     */
+    @Override
+    public void onCompletion(CountedCompleter<?> caller) {
+        spliterator = null;
+        leftChild = rightChild = null;
+    }
+
+    /**
+     * Determines if the task can be computed.
+     *
+     * @implSpec The default always returns true
+     *
+     * @return {@code true} if this task can be computed to either calculate the
+     *         leaf via {@link #doLeaf()} or split, otherwise false if this task
+     *         cannot be computed, for example if this task has been canceled
+     *         and/or a result for the computation has been found by another
+     *         task.
+     */
+    protected boolean canCompute() {
+        return true;
+    }
+
+    /**
+     * Returns whether this node is a "leftmost" node -- whether the path from
+     * the root to this node involves only traversing leftmost child links.  For
+     * a leaf node, this means it is the first leaf node in the encounter order.
+     *
+     * @return {@code true} if this node is a "leftmost" node
+     */
+    protected boolean isLeftmostNode() {
+        @SuppressWarnings("unchecked")
+        K node = (K) this;
+        while (node != null) {
+            K parent = node.getParent();
+            if (parent != null && parent.leftChild != node)
+                return false;
+            node = parent;
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/util/stream/BaseStream.java	Tue Apr 23 11:13:38 2013 +0100
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2012, 2013, 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;
+
+import java.util.Iterator;
+import java.util.Spliterator;
+
+/**
+ * Base interface for stream types such as {@link Stream}, {@link IntStream},
+ * etc.  Contains methods common to all stream types.  Many of these methods
+ * are implemented by {@link AbstractPipeline}, even though
+ * {@code AbstractPipeline} does not directly implement {@code BaseStream}.
+ *
+ * @param <T> type of stream elements
+ * @param <S> type of stream implementing {@code BaseStream}
+ * @since 1.8
+ */
+interface BaseStream<T, S extends BaseStream<T, S>> {
+    /**
+     * Returns an iterator for the elements of this stream.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @return the element iterator for this stream
+     */
+    Iterator<T> iterator();
+
+    /**
+     * Returns a spliterator for the elements of this stream.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @return the element spliterator for this stream
+     */
+    Spliterator<T> spliterator();
+
+    /**
+     * Returns whether this stream, when executed, would execute in parallel
+     * (assuming no further modification of the stream, such as appending
+     * further intermediate operations or changing its parallelism).  Calling
+     * this method after invoking an intermediate or terminal stream operation
+     * method may yield unpredictable results.
+     *
+     * @return {@code true} if this stream would execute in parallel if executed
+     * without further modification otherwise {@code false}
+     */
+    boolean isParallel();
+
+    /**
+     * Returns an equivalent stream that is sequential.  May return
+     * itself, either because the stream was already sequential, or because
+     * the underlying stream state was modified to be sequential.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @return a sequential stream
+     */
+    S sequential();
+
+    /**
+     * Returns an equivalent stream that is parallel.  May return
+     * itself, either because the stream was already parallel, or because
+     * the underlying stream state was modified to be parallel.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @return a parallel stream
+     */
+    S parallel();
+
+    /**
+     * Returns an equivalent stream that is
+     * <a href="package-summary.html#Ordering">unordered</a>.  May return
+     * itself if the stream was already unordered.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @return an unordered stream
+     */
+    S unordered();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/util/stream/CloseableStream.java	Tue Apr 23 11:13:38 2013 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2013, 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;
+
+/**
+ * A {@code CloseableStream} is a {@code Stream} that can be closed.
+ * The close method is invoked to release resources that the object is
+ * holding (such as open files).
+ *
+ * @param <T> The type of stream elements
+ * @since 1.8
+ */
+public interface CloseableStream<T> extends Stream<T>, AutoCloseable {
+
+    /**
+     * Closes this resource, relinquishing any underlying resources.
+     * This method is invoked automatically on objects managed by the
+     * {@code try}-with-resources statement.  Does nothing if called when
+     * the resource has already been closed.
+     *
+     * This method does not allow throwing checked {@code Exception}s like
+     * {@link AutoCloseable#close() AutoCloseable.close()}. Cases where the
+     * close operation may fail require careful attention by implementers. It
+     * is strongly advised to relinquish the underlying resources and to
+     * internally <em>mark</em> the resource as closed. The {@code close}
+     * method is unlikely to be invoked more than once and so this ensures
+     * that the resources are released in a timely manner. Furthermore it
+     * reduces problems that could arise when the resource wraps, or is
+     * wrapped, by another resource.
+     *
+     * @see AutoCloseable#close()
+     */
+    void close();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/util/stream/Collector.java	Tue Apr 23 11:13:38 2013 +0100
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2012, 2013, 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;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.BinaryOperator;
+import java.util.function.Supplier;
+
+/**
+ * A <a href="package-summary.html#Reduction">reduction operation</a> that
+ * supports folding input elements into a cumulative result.  The result may be
+ * a value or may be a mutable result container.  Examples of operations
+ * accumulating results into a mutable result container include: accumulating
+ * input elements into a {@code Collection}; concatenating strings into a
+ * {@code StringBuilder}; computing summary information about elements such as
+ * sum, min, max, or average; computing "pivot table" summaries such as "maximum
+ * valued transaction by seller", etc.  Reduction operations can be performed
+ * either sequentially or in parallel.
+ *
+ * <p>The following are examples of using the predefined {@code Collector}
+ * implementations in {@link Collectors} with the {@code Stream} API to perform
+ * mutable reduction tasks:
+ * <pre>{@code
+ *     // Accumulate elements into a List
+ *     List<String> list = stream.collect(Collectors.toList());
+ *
+ *     // Accumulate elements into a TreeSet
+ *     Set<String> list = stream.collect(Collectors.toCollection(TreeSet::new));
+ *
+ *     // Convert elements to strings and concatenate them, separated by commas
+ *     String joined = stream.map(Object::toString)
+ *                           .collect(Collectors.toStringJoiner(", "))
+ *                           .toString();
+ *
+ *     // Find highest-paid employee
+ *     Employee highestPaid = employees.stream()
+ *                                     .collect(Collectors.maxBy(Comparators.comparing(Employee::getSalary)));
+ *
+ *     // Group employees by department
+ *     Map<Department, List<Employee>> byDept
+ *         = employees.stream()
+ *                    .collect(Collectors.groupingBy(Employee::getDepartment));
+ *
+ *     // Find highest-paid employee by department
+ *     Map<Department, Employee> highestPaidByDept
+ *         = employees.stream()
+ *                    .collect(Collectors.groupingBy(Employee::getDepartment,
+ *                                                   Collectors.maxBy(Comparators.comparing(Employee::getSalary))));
+ *
+ *     // Partition students into passing and failing
+ *     Map<Boolean, List<Student>> passingFailing =
+ *         students.stream()
+ *                 .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD);
+ *
+ * }</pre>
+ *
+ * <p>A {@code Collector} is specified by three functions that work together to
+ * manage a result or result container.  They are: creation of an initial
+ * result, incorporating a new data element into a result, and combining two
+ * results into one. The last function -- combining two results into one -- is
+ * used during parallel operations, where subsets of the input are accumulated
+ * in parallel, and then the subresults merged into a combined result. The
+ * result may be a mutable container or a value.  If the result is mutable, the
+ * accumulation and combination functions may either mutate their left argument
+ * and return that (such as adding elements to a collection), or return a new
+ * result, in which case it should not perform any mutation.
+ *
+ * <p>Collectors also have a set of characteristics, including
+ * {@link Characteristics#CONCURRENT} and
+ * {@link Characteristics#STRICTLY_MUTATIVE}.  These characteristics provide
+ * hints that can be used by a reduction implementation to provide better
+ * performance.
+ *
+ * <p>Libraries that implement reduction based on {@code Collector}, such as
+ * {@link Stream#collect(Collector)}, must adhere to the following constraints:
+ * <ul>
+ *     <li>The first argument passed to the accumulator function, and both
+ *     arguments passed to the combiner function, must be the result of a
+ *     previous invocation of {@link #resultSupplier()}, {@link #accumulator()},
+ *     or {@link #combiner()}.</li>
+ *     <li>The implementation should not do anything with the result of any of
+ *     the result supplier, accumulator, or combiner functions other than to
+ *     pass them again to the accumulator or combiner functions, or return them
+ *     to the caller of the reduction operation.</li>
+ *     <li>If a result is passed to the accumulator or combiner function, and
+ *     the same object is not returned from that function, it is never used
+ *     again.</li>
+ *     <li>Once a result is passed to the combiner function, it is never passed
+ *     to the accumulator function again.</li>
+ *     <li>For non-concurrent collectors, any result returned from the result
+ *     supplier, accumulator, or combiner functions must be serially
+ *     thread-confined.  This enables collection to occur in parallel without
+ *     the {@code Collector} needing to implement any additional synchronization.
+ *     The reduction implementation must manage that the input is properly
+ *     partitioned, that partitions are processed in isolation, and combining
+ *     happens only after accumulation is complete.</li>
+ *     <li>For concurrent collectors, an implementation is free to (but not
+ *     required to) implement reduction concurrently.  A concurrent reduction
+ *     is one where the accumulator function is called concurrently from
+ *     multiple threads, using the same concurrently-modifiable result container,
+ *     rather than keeping the result isolated during accumulation.
+ *     A concurrent reduction should only be applied if the collector has the
+ *     {@link Characteristics#UNORDERED} characteristics or if the
+ *     originating data is unordered.</li>
+ * </ul>
+ *
+ * @apiNote
+ * Performing a reduction operation with a {@code Collector} should produce a
+ * result equivalent to:
+ * <pre>{@code
+ *     BiFunction<R,T,R> accumulator = collector.accumulator();
+ *     R result = collector.resultSupplier().get();
+ *     for (T t : data)
+ *         result = accumulator.apply(result, t);
+ *     return result;
+ * }</pre>
+ *
+ * <p>However, the library is free to partition the input, perform the reduction
+ * on the partitions, and then use the combiner function to combine the partial
+ * results to achieve a parallel reduction.  Depending on the specific reduction
+ * operation, this may perform better or worse, depending on the relative cost
+ * of the accumulator and combiner functions.
+ *
+ * <p>An example of an operation that can be easily modeled by {@code Collector}
+ * is accumulating elements into a {@code TreeSet}. In this case, the {@code
+ * resultSupplier()} function is {@code () -> new Treeset<T>()}, the
+ * {@code accumulator} function is
+ * {@code (set, element) -> { set.add(element); return set; }}, and the combiner
+ * function is {@code (left, right) -> { left.addAll(right); return left; }}.
+ * (This behavior is implemented by
+ * {@code Collectors.toCollection(TreeSet::new)}).
+ *
+ * TODO Associativity and commutativity
+ *
+ * @see Stream#collect(Collector)
+ * @see Collectors
+ *
+ * @param <T> the type of input element to the collect operation
+ * @param <R> the result type of the collect operation
+ * @since 1.8
+ */
+public interface Collector<T, R> {
+    /**
+     * A function that creates and returns a new result that represents
+     * "no values".  If the accumulator or combiner functions may mutate their
+     * arguments, this must be a new, empty result container.
+     *
+     * @return a function which, when invoked, returns a result representing
+     * "no values"
+     */
+    Supplier<R> resultSupplier();
+
+    /**
+     * A function that folds a new value into a cumulative result.  The result
+     * may be a mutable result container or a value.  The accumulator function
+     * may modify a mutable container and return it, or create a new result and
+     * return that, but if it returns a new result object, it must not modify
+     * any of its arguments.
+     *
+     * <p>If the collector has the {@link Characteristics#STRICTLY_MUTATIVE}
+     * characteristic, then the accumulator function <em>must</em> always return
+     * its first argument, after possibly mutating its state.
+     *
+     * @return a function which folds a new value into a cumulative result
+     */
+    BiFunction<R, T, R> accumulator();
+
+    /**
+     * A function that accepts two partial results and merges them.  The
+     * combiner function may fold state from one argument into the other and
+     * return that, or may return a new result object, but if it returns
+     * a new result object, it must not modify the state of either of its
+     * arguments.
+     *
+     * <p>If the collector has the {@link Characteristics#STRICTLY_MUTATIVE}
+     * characteristic, then the combiner function <em>must</em> always return
+     * its first argument, after possibly mutating its state.
+     *
+     * @return a function which combines two partial results into a cumulative
+     * result
+     */
+    BinaryOperator<R> combiner();
+
+    /**
+     * Returns a {@code Set} of {@code Collector.Characteristics} indicating
+     * the characteristics of this Collector.  This set should be immutable.
+     *
+     * @return an immutable set of collector characteristics
+     */
+    Set<Characteristics> characteristics();
+
+    /**
+     * Characteristics indicating properties of a {@code Collector}, which can
+     * be used to optimize reduction implementations.
+     */
+    enum Characteristics {
+        /**
+         * Indicates that this collector is <em>concurrent</em>, meaning that
+         * the result container can support the accumulator function being
+         * called concurrently with the same result container from multiple
+         * threads. Concurrent collectors must also always have the
+         * {@code STRICTLY_MUTATIVE} characteristic.
+         *
+         * <p>If a {@code CONCURRENT} collector is not also {@code UNORDERED},
+         * then it should only be evaluated concurrently if applied to an
+         * unordered data source.
+         */
+        CONCURRENT,
+
+        /**
+         * Indicates that the result container has no intrinsic order, such as
+         * a {@link Set}.
+         */
+        UNORDERED,
+
+        /**
+         * Indicates that this collector operates by strict mutation of its
+         * result container. This means that the {@link #accumulator()} and
+         * {@link #combiner()} functions will always modify the state of and
+         * return their first argument, rather than returning a different result
+         * container.
+         */
+        STRICTLY_MUTATIVE
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/util/stream/DelegatingStream.java	Tue Apr 23 11:13:38 2013 +0100
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2013, 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;
+
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Spliterator;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.BinaryOperator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.IntFunction;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+
+/**
+ * A {@code Stream} implementation that delegates operations to another {@code
+ * Stream}.
+ *
+ * @param <T> type of stream elements for this stream and underlying delegate
+ * stream
+ *
+ * @since 1.8
+ */
+public class DelegatingStream<T> implements Stream<T> {
+    final private Stream<T> delegate;
+
+    /**
+     * Construct a {@code Stream} that delegates operations to another {@code
+     * Stream}.
+     *
+     * @param delegate the underlying {@link Stream} to which we delegate all
+     *                 {@code Stream} methods
+     * @throws NullPointerException if the delegate is null
+     */
+    public DelegatingStream(Stream<T> delegate) {
+        this.delegate = Objects.requireNonNull(delegate);
+    }
+
+    // -- BaseStream methods --
+
+    @Override
+    public Spliterator<T> spliterator() {
+        return delegate.spliterator();
+    }
+
+    @Override
+    public boolean isParallel() {
+        return delegate.isParallel();
+    }
+
+    @Override
+    public Iterator<T> iterator() {
+        return delegate.iterator();
+    }
+
+    // -- Stream methods --
+
+    @Override
+    public Stream<T> filter(Predicate<? super T> predicate) {
+        return delegate.filter(predicate);
+    }
+
+    @Override
+    public <R> Stream<R> map(Function<? super T, ? extends R> mapper) {
+        return delegate.map(mapper);
+    }
+
+    @Override
+    public IntStream mapToInt(ToIntFunction<? super T> mapper) {
+        return delegate.mapToInt(mapper);
+    }
+
+    @Override
+    public LongStream mapToLong(ToLongFunction<? super T> mapper) {
+        return delegate.mapToLong(mapper);
+    }
+
+    @Override
+    public DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper) {
+        return delegate.mapToDouble(mapper);
+    }
+
+    @Override
+    public <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) {
+        return delegate.flatMap(mapper);
+    }
+
+    @Override
+    public IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper) {
+        return delegate.flatMapToInt(mapper);
+    }
+
+    @Override
+    public LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper) {
+        return delegate.flatMapToLong(mapper);
+    }
+
+    @Override
+    public DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper) {
+        return delegate.flatMapToDouble(mapper);
+    }
+
+    @Override
+    public Stream<T> distinct() {
+        return delegate.distinct();
+    }
+
+    @Override
+    public Stream<T> sorted() {
+        return delegate.sorted();
+    }
+
+    @Override
+    public Stream<T> sorted(Comparator<? super T> comparator) {
+        return delegate.sorted(comparator);
+    }
+
+    @Override
+    public void forEach(Consumer<? super T> action) {
+        delegate.forEach(action);
+    }
+
+    @Override
+    public void forEachOrdered(Consumer<? super T> action) {
+        delegate.forEachOrdered(action);
+    }
+
+    @Override
+    public Stream<T> peek(Consumer<? super T> consumer) {
+        return delegate.peek(consumer);
+    }
+
+    @Override
+    public Stream<T> limit(long maxSize) {
+        return delegate.limit(maxSize);
+    }
+
+    @Override
+    public Stream<T> substream(long startingOffset) {
+        return delegate.substream(startingOffset);
+    }
+
+    @Override
+    public Stream<T> substream(long startingOffset, long endingOffset) {
+        return delegate.substream(startingOffset, endingOffset);
+    }
+
+    @Override
+    public <A> A[] toArray(IntFunction<A[]> generator) {
+        return delegate.toArray(generator);
+    }
+
+    @Override
+    public Object[] toArray() {
+        return delegate.toArray();
+    }
+
+    @Override
+    public T reduce(T identity, BinaryOperator<T> accumulator) {
+        return delegate.reduce(identity, accumulator);
+    }
+
+    @Override
+    public Optional<T> reduce(BinaryOperator<T> accumulator) {
+        return delegate.reduce(accumulator);
+    }
+
+    @Override
+    public <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator,
+                        BinaryOperator<U> combiner) {
+        return delegate.reduce(identity, accumulator, combiner);
+    }
+
+    @Override
+    public <R> R collect(Supplier<R> resultFactory,
+                         BiConsumer<R, ? super T> accumulator,
+                         BiConsumer<R, R> combiner) {
+        return delegate.collect(resultFactory, accumulator, combiner);
+    }
+
+    @Override
+    public <R> R collect(Collector<? super T, R> collector) {
+        return delegate.collect(collector);
+    }
+
+    @Override
+    public Optional<T> max(Comparator<? super T> comparator) {
+        return delegate.max(comparator);
+    }
+
+    @Override
+    public Optional<T> min(Comparator<? super T> comparator) {
+        return delegate.min(comparator);
+    }
+
+    @Override
+    public long count() {
+        return delegate.count();
+    }
+
+    @Override
+    public boolean anyMatch(Predicate<? super T> predicate) {
+        return delegate.anyMatch(predicate);
+    }
+
+    @Override
+    public boolean allMatch(Predicate<? super T> predicate) {
+        return delegate.allMatch(predicate);
+    }
+
+    @Override
+    public boolean noneMatch(Predicate<? super T> predicate) {
+        return delegate.noneMatch(predicate);
+    }
+
+    @Override
+    public Optional<T> findFirst() {
+        return delegate.findFirst();
+    }
+
+    @Override
+    public Optional<T> findAny() {
+        return delegate.findAny();
+    }
+
+    @Override
+    public Stream<T> unordered() {
+        return delegate.unordered();
+    }
+
+    @Override
+    public Stream<T> sequential() {
+        return delegate.sequential();
+    }
+
+    @Override
+    public Stream<T> parallel() {
+        return delegate.parallel();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/util/stream/DoubleStream.java	Tue Apr 23 11:13:38 2013 +0100
@@ -0,0 +1,652 @@
+/*
+ * Copyright (c) 2012, 2013, 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;
+
+import java.util.DoubleSummaryStatistics;
+import java.util.OptionalDouble;
+import java.util.PrimitiveIterator;
+import java.util.Spliterator;
+import java.util.function.BiConsumer;
+import java.util.function.DoubleBinaryOperator;
+import java.util.function.DoubleConsumer;
+import java.util.function.DoubleFunction;
+import java.util.function.DoublePredicate;
+import java.util.function.DoubleToIntFunction;
+import java.util.function.DoubleToLongFunction;
+import java.util.function.DoubleUnaryOperator;
+import java.util.function.Function;
+import java.util.function.ObjDoubleConsumer;
+import java.util.function.Supplier;
+
+/**
+ * A sequence of primitive double elements supporting sequential and parallel
+ * bulk operations. Streams support lazy intermediate operations (transforming
+ * a stream to another stream) such as {@code filter} and {@code map}, and terminal
+ * operations (consuming the contents of a stream to produce a result or
+ * side-effect), such as {@code forEach}, {@code findFirst}, and {@code
+ * iterator}.  Once an operation has been performed on a stream, it
+ * is considered <em>consumed</em> and no longer usable for other operations.
+ *
+ * <p>For sequential stream pipelines, all operations are performed in the
+ * <a href="package-summary.html#Ordering">encounter order</a> of the pipeline
+ * source, if the pipeline source has a defined encounter order.
+ *
+ * <p>For parallel stream pipelines, unless otherwise specified, intermediate
+ * stream operations preserve the <a href="package-summary.html#Ordering">
+ * encounter order</a> of their source, and terminal operations
+ * respect the encounter order of their source, if the source
+ * has an encounter order.  Provided that and parameters to stream operations
+ * satisfy the <a href="package-summary.html#NonInterference">non-interference
+ * requirements</a>, and excepting differences arising from the absence of
+ * a defined encounter order, the result of a stream pipeline should be the
+ * stable across multiple executions of the same operations on the same source.
+ * However, the timing and thread in which side-effects occur (for those
+ * operations which are allowed to produce side-effects, such as
+ * {@link #forEach(DoubleConsumer)}), are explicitly nondeterministic for parallel
+ * execution of stream pipelines.
+ *
+ * <p>Unless otherwise noted, passing a {@code null} argument to any stream
+ * method may result in a {@link NullPointerException}.
+ *
+ * @apiNote
+ * Streams are not data structures; they do not manage the storage for their
+ * elements, nor do they support access to individual elements.  However,
+ * you can use the {@link #iterator()} or {@link #spliterator()} operations to
+ * perform a controlled traversal.
+ *
+ * @since 1.8
+ * @see <a href="package-summary.html">java.util.stream</a>
+ */
+public interface DoubleStream extends BaseStream<Double, DoubleStream> {
+
+    /**
+     * Returns a stream consisting of the elements of this stream that match
+     * the given predicate.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param predicate a <a href="package-summary.html#NonInterference">
+     *                  non-interfering, stateless</a> predicate to apply to
+     *                  each element to determine if it should be included
+     * @return the new stream
+     */
+    DoubleStream filter(DoublePredicate predicate);
+
+    /**
+     * Returns a stream consisting of the results of applying the given
+     * function to the elements of this stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to
+     *               each element
+     * @return the new stream
+     */
+    DoubleStream map(DoubleUnaryOperator mapper);
+
+    /**
+     * Returns an object-valued {@code Stream} consisting of the results of
+     * applying the given function to the elements of this stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">
+     *     intermediate operation</a>.
+     *
+     * @param <U> the element type of the new stream
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to each
+     *               element
+     * @return the new stream
+     */
+    <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper);
+
+    /**
+     * Returns an {@code IntStream} consisting of the results of applying the
+     * given function to the elements of this stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to each
+     *               element
+     * @return the new stream
+     */
+    IntStream mapToInt(DoubleToIntFunction mapper);
+
+    /**
+     * Returns a {@code LongStream} consisting of the results of applying the
+     * given function to the elements of this stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to each
+     *               element
+     * @return the new stream
+     */
+    LongStream mapToLong(DoubleToLongFunction mapper);
+
+    /**
+     * Returns a stream consisting of the results of replacing each element of
+     * this stream with the contents of the stream produced by applying the
+     * provided mapping function to each element.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @apiNote
+     * The {@code flatMap()} operation has the effect of applying a one-to-many
+     * tranformation to the elements of the stream, and then flattening the
+     * resulting elements into a new stream. For example, if {@code orders}
+     * is a stream of purchase orders, and each purchase order contains a
+     * collection of line items, then the following produces a stream of line
+     * items:
+     * <pre>{@code
+     *     orderStream.flatMap(order -> order.getLineItems().stream())...
+     * }</pre>
+     *
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to
+     *               each element which produces an {@code DoubleStream} of new
+     *               values
+     * @return the new stream
+     * @see Stream#flatMap(Function)
+     */
+    DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper);
+
+    /**
+     * Returns a stream consisting of the distinct elements of this stream. The
+     * elements are compared for equality according to
+     * {@link java.lang.Double#compare(double, double)}.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">stateful
+     * intermediate operation</a>.
+     *
+     * @return the result stream
+     */
+    DoubleStream distinct();
+
+    /**
+     * Returns a stream consisting of the elements of this stream in sorted
+     * order. The elements are compared for equality according to
+     * {@link java.lang.Double#compare(double, double)}.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">stateful
+     * intermediate operation</a>.
+     *
+     * @return the result stream
+     */
+    DoubleStream sorted();
+
+    /**
+     * Returns a stream consisting of the elements of this stream, additionally
+     * performing the provided action on each element as elements are consumed
+     * from the resulting stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * <p>For parallel stream pipelines, the action may be called at
+     * whatever time and in whatever thread the element is made available by the
+     * upstream operation.  If the action modifies shared state,
+     * it is responsible for providing the required synchronization.
+     *
+     * @apiNote This method exists mainly to support debugging, where you want
+     * to see the elements as they flow past a certain point in a pipeline:
+     * <pre>{@code
+     *     list.stream()
+     *         .filter(filteringFunction)
+     *         .peek(e -> {System.out.println("Filtered value: " + e); });
+     *         .map(mappingFunction)
+     *         .peek(e -> {System.out.println("Mapped value: " + e); });
+     *         .collect(Collectors.toDoubleSummaryStastistics());
+     * }</pre>
+     *
+     * @param consumer a <a href="package-summary.html#NonInterference">
+     *                 non-interfering</a> action to perform on the elements as
+     *                 they are consumed from the stream
+     * @return the new stream
+     */
+    DoubleStream peek(DoubleConsumer consumer);
+
+    /**
+     * Returns a stream consisting of the elements of this stream, truncated
+     * to be no longer than {@code maxSize} in length.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * stateful intermediate operation</a>.
+     *
+     * @param maxSize the number of elements the stream should be limited to
+     * @return the new stream
+     * @throws IllegalArgumentException if {@code maxSize} is negative
+     */
+    DoubleStream limit(long maxSize);
+
+    /**
+     * Returns a stream consisting of the remaining elements of this stream
+     * after indexing {@code startInclusive} elements into the stream. If the
+     * {@code startInclusive} index lies past the end of this stream then an
+     * empty stream will be returned.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">stateful
+     * intermediate operation</a>.
+     *
+     * @param startInclusive the number of leading elements to skip
+     * @return the new stream
+     * @throws IllegalArgumentException if {@code startInclusive} is negative
+     */
+    DoubleStream substream(long startInclusive);
+
+    /**
+     * Returns a stream consisting of the remaining elements of this stream
+     * after indexing {@code startInclusive} elements into the stream and
+     * truncated to contain no more than {@code endExclusive - startInclusive}
+     * elements. If the {@code startInclusive} index lies past the end
+     * of this stream then an empty stream will be returned.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * stateful intermediate operation</a>.
+     *
+     * @param startInclusive the starting position of the substream, inclusive
+     * @param endExclusive the ending position of the substream, exclusive
+     * @return the new stream
+     * @throws IllegalArgumentException if {@code startInclusive} or
+     * {@code endExclusive} is negative or {@code startInclusive} is greater
+     * than {@code endExclusive}
+     */
+    DoubleStream substream(long startInclusive, long endExclusive);
+
+    /**
+     * Performs an action for each element of this stream.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * <p>For parallel stream pipelines, this operation does <em>not</em>
+     * guarantee to respect the encounter order of the stream, as doing so
+     * would sacrifice the benefit of parallelism.  For any given element, the
+     * action may be performed at whatever time and in whatever thread the
+     * library chooses.  If the action accesses shared state, it is
+     * responsible for providing the required synchronization.
+     *
+     * @param action a <a href="package-summary.html#NonInterference">
+     *               non-interfering</a> action to perform on the elements
+     */
+    void forEach(DoubleConsumer action);
+
+    /**
+     * Performs an action for each element of this stream, guaranteeing that
+     * each element is processed in encounter order for streams that have a
+     * defined encounter order.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @param action a <a href="package-summary.html#NonInterference">
+     *               non-interfering</a> action to perform on the elements
+     * @see #forEach(DoubleConsumer)
+     */
+    void forEachOrdered(DoubleConsumer action);
+
+    /**
+     * Returns an array containing the elements of this stream.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @return an array containing the elements of this stream
+     */
+    double[] toArray();
+
+    /**
+     * Performs a <a href="package-summary.html#Reduction">reduction</a> on the
+     * elements of this stream, using the provided identity value and an
+     * <a href="package-summary.html#Associativity">associative</a>
+     * accumulation function, and returns the reduced value.  This is equivalent
+     * to:
+     * <pre>{@code
+     *     double result = identity;
+     *     for (double element : this stream)
+     *         result = accumulator.apply(result, element)
+     *     return result;
+     * }</pre>
+     *
+     * but is not constrained to execute sequentially.
+     *
+     * <p>The {@code identity} value must be an identity for the accumulator
+     * function. This means that for all {@code x},
+     * {@code accumulator.apply(identity, x)} is equal to {@code x}.
+     * The {@code accumulator} function must be an
+     * <a href="package-summary.html#Associativity">associative</a> function.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @apiNote Sum, min, max, and average are all special cases of reduction.
+     * Summing a stream of numbers can be expressed as:
+
+     * <pre>{@code
+     *     double sum = numbers.reduce(0, (a, b) -> a+b);
+     * }</pre>
+     *
+     * or more compactly:
+     *
+     * <pre>{@code
+     *     double sum = numbers.reduce(0, Double::sum);
+     * }</pre>
+     *
+     * <p>While this may seem a more roundabout way to perform an aggregation
+     * compared to simply mutating a running total in a loop, reduction
+     * operations parallelize more gracefully, without needing additional
+     * synchronization and with greatly reduced risk of data races.
+     *
+     * @param identity the identity value for the accumulating function
+     * @param op an <a href="package-summary.html#Associativity">associative</a>
+     *                    <a href="package-summary.html#NonInterference">non-interfering,
+     *                    stateless</a> function for combining two values
+     * @return the result of the reduction
+     * @see #sum()
+     * @see #min()
+     * @see #max()
+     * @see #average()
+     */
+    double reduce(double identity, DoubleBinaryOperator op);
+
+    /**
+     * Performs a <a href="package-summary.html#Reduction">reduction</a> on the
+     * elements of this stream, using an
+     * <a href="package-summary.html#Associativity">associative</a> accumulation
+     * function, and returns an {@code OptionalDouble} describing the reduced
+     * value, if any. This is equivalent to:
+     * <pre>{@code
+     *     boolean foundAny = false;
+     *     double result = null;
+     *     for (double element : this stream) {
+     *         if (!foundAny) {
+     *             foundAny = true;
+     *             result = element;
+     *         }
+     *         else
+     *             result = accumulator.apply(result, element);
+     *     }
+     *     return foundAny ? OptionalDouble.of(result) : OptionalDouble.empty();
+     * }</pre>
+     *
+     * but is not constrained to execute sequentially.
+     *
+     * <p>The {@code accumulator} function must be an
+     * <a href="package-summary.html#Associativity">associative</a> function.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @param op an <a href="package-summary.html#Associativity">associative</a>
+     *           <a href="package-summary.html#NonInterference">non-interfering,
+     *           stateless</a> function for combining two values
+     * @return the result of the reduction
+     * @see #reduce(double, DoubleBinaryOperator)
+     */
+    OptionalDouble reduce(DoubleBinaryOperator op);
+
+    /**
+     * Performs a <a href="package-summary.html#MutableReduction">mutable
+     * reduction</a> operation on the elements of this stream.  A mutable
+     * reduction is one in which the reduced value is a mutable value holder,
+     * such as an {@code ArrayList}, and elements are incorporated by updating
+     * the state of the result, rather than by replacing the result.  This
+     * produces a result equivalent to:
+     * <pre>{@code
+     *     R result = resultFactory.get();
+     *     for (double element : this stream)
+     *         accumulator.accept(result, element);
+     *     return result;
+     * }</pre>
+     *
+     * <p>Like {@link #reduce(double, DoubleBinaryOperator)}, {@code collect}
+     * operations can be parallelized without requiring additional
+     * synchronization.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @param <R> type of the result
+     * @param resultFactory a function that creates a new result container.
+     *                      For a parallel execution, this function may be
+     *                      called multiple times and must return a fresh value
+     *                      each time.
+     * @param accumulator an <a href="package-summary.html#Associativity">associative</a>
+     *                    <a href="package-summary.html#NonInterference">non-interfering,
+     *                    stateless</a> function for incorporating an additional
+     *                    element into a result
+     * @param combiner an <a href="package-summary.html#Associativity">associative</a>
+     *                 <a href="package-summary.html#NonInterference">non-interfering,
+     *                 stateless</a> function for combining two values, which
+     *                 must be compatible with the accumulator function
+     * @return the result of the reduction
+     * @see Stream#collect(Supplier, BiConsumer, BiConsumer)
+     */
+    <R> R collect(Supplier<R> resultFactory,
+                  ObjDoubleConsumer<R> accumulator,
+                  BiConsumer<R, R> combiner);
+
+    /**
+     * Returns the sum of elements in this stream.  The sum returned can vary
+     * depending upon the order in which elements are encountered.  This is due
+     * to accumulated rounding error in addition of values of differing
+     * magnitudes. Elements sorted by increasing absolute magnitude tend to
+     * yield more accurate results.  If any stream element is a {@code NaN} or
+     * the sum is at any point a {@code NaN} then the sum will be {@code NaN}.
+     * This is a special case of a
+     * <a href="package-summary.html#MutableReduction">reduction</a> and is
+     * equivalent to:
+     * <pre>{@code
+     *     return reduce(0, Double::sum);
+     * }</pre>
+     *
+     * @return the sum of elements in this stream
+     */
+    double sum();
+
+    /**
+     * Returns an {@code OptionalDouble} describing the minimum element of this
+     * stream, or an empty OptionalDouble if this stream is empty.  The minimum
+     * element will be {@code Double.NaN} if any stream element was NaN. Unlike
+     * the numerical comparison operators, this method considers negative zero
+     * to be strictly smaller than positive zero. This is a special case of a
+     * <a href="package-summary.html#MutableReduction">reduction</a> and is
+     * equivalent to:
+     * <pre>{@code
+     *     return reduce(Double::min);
+     * }</pre>
+     *
+     * @return an {@code OptionalDouble} containing the minimum element of this
+     * stream, or an empty optional if the stream is empty
+     */
+    OptionalDouble min();
+
+    /**
+     * Returns an {@code OptionalDouble} describing the maximum element of this
+     * stream, or an empty OptionalDouble if this stream is empty.  The maximum
+     * element will be {@code Double.NaN} if any stream element was NaN. Unlike
+     * the numerical comparison operators, this method considers negative zero
+     * to be strictly smaller than positive zero. This is a
+     * special case of a
+     * <a href="package-summary.html#MutableReduction">reduction</a> and is
+     * equivalent to:
+     * <pre>{@code
+     *     return reduce(Double::max);
+     * }</pre>
+     *
+     * @return an {@code OptionalDouble} containing the maximum element of this
+     * stream, or an empty optional if the stream is empty
+     */
+    OptionalDouble max();
+
+    /**
+     * Returns the count of elements in this stream.  This is a special case of
+     * a <a href="package-summary.html#MutableReduction">reduction</a> and is
+     * equivalent to:
+     * <pre>{@code
+     *     return mapToLong(e -> 1L).sum();
+     * }</pre>
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>.
+     *
+     * @return the count of elements in this stream
+     */
+    long count();
+
+    /**
+     * Returns an {@code OptionalDouble} describing the average of elements of
+     * this stream, or an empty optional if this stream is empty.  The average
+     * returned can vary depending upon the order in which elements are
+     * encountered. This is due to accumulated rounding error in addition of
+     * elements of differing magnitudes. Elements sorted by increasing absolute
+     * magnitude tend to yield more accurate results. If any recorded value is
+     * a {@code NaN} or the sum is at any point a {@code NaN} then the average
+     * will be {@code NaN}. This is a special case of a
+     * <a href="package-summary.html#MutableReduction">reduction</a>.
+     *
+     * @return an {@code OptionalDouble} containing the average element of this
+     * stream, or an empty optional if the stream is empty
+     */
+    OptionalDouble average();
+
+    /**
+     * Returns a {@code DoubleSummaryStatistics} describing various summary data
+     * about the elements of this stream.  This is a special
+     * case of a <a href="package-summary.html#MutableReduction">reduction</a>.
+     *
+     * @return a {@code DoubleSummaryStatistics} describing various summary data
+     * about the elements of this stream
+     */
+    DoubleSummaryStatistics summaryStatistics();
+
+    /**
+     * Returns whether any elements of this stream match the provided
+     * predicate.  May not evaluate the predicate on all elements if not
+     * necessary for determining the result.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * terminal operation</a>.
+     *
+     * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
+     *                  stateless</a> predicate to apply to elements of this
+     *                  stream
+     * @return {@code true} if any elements of the stream match the provided
+     * predicate otherwise {@code false}
+     */
+    boolean anyMatch(DoublePredicate predicate);
+
+    /**
+     * Returns whether all elements of this stream match the provided predicate.
+     * May not evaluate the predicate on all elements if not necessary for
+     * determining the result.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * terminal operation</a>.
+     *
+     * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
+     *                  stateless</a> predicate to apply to elements of this
+     *                  stream
+     * @return {@code true} if all elements of the stream match the provided
+     * predicate otherwise {@code false}
+     */
+    boolean allMatch(DoublePredicate predicate);
+
+    /**
+     * Returns whether no elements of this stream match the provided predicate.
+     * May not evaluate the predicate on all elements if not necessary for
+     * determining the result.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * terminal operation</a>.
+     *
+     * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
+     *                  stateless</a> predicate to apply to elements of this
+     *                  stream
+     * @return {@code true} if no elements of the stream match the provided
+     * predicate otherwise {@code false}
+     */
+    boolean noneMatch(DoublePredicate predicate);
+
+    /**
+     * Returns an {@link OptionalDouble} describing the first element of this
+     * stream (in the encounter order), or an empty {@code OptionalDouble} if
+     * the stream is empty.  If the stream has no encounter order, than any
+     * element may be returned.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * terminal operation</a>.
+     *
+     * @return an {@code OptionalDouble} describing the first element of this
+     * stream, or an empty {@code OptionalDouble} if the stream is empty
+     */
+    OptionalDouble findFirst();
+
+    /**
+     * Returns an {@link OptionalDouble} describing some element of the stream,
+     * or an empty {@code OptionalDouble} if the stream is empty.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * terminal operation</a>.
+     *
+     * <p>The behavior of this operation is explicitly nondeterministic; it is
+     * free to select any element in the stream.  This is to allow for maximal
+     * performance in parallel operations; the cost is that multiple invocations
+     * on the same source may not return the same result.  (If the first element
+     * in the encounter order is desired, use {@link #findFirst()} instead.)
+     *
+     * @return an {@code OptionalDouble} describing some element of this stream,
+     * or an empty {@code OptionalDouble} if the stream is empty
+     * @see #findFirst()
+     */
+    OptionalDouble findAny();
+
+    /**
+     * Returns a {@code Stream} consisting of the elements of this stream,
+     * boxed to {@code Double}.
+     *
+     * @return a {@code Stream} consistent of the elements of this stream,
+     * each boxed to a {@code Double}
+     */
+    Stream<Double> boxed();
+
+    @Override
+    DoubleStream sequential();
+
+    @Override
+    DoubleStream parallel();
+
+    @Override
+    PrimitiveIterator.OfDouble iterator();
+
+    @Override
+    Spliterator.OfDouble spliterator();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/util/stream/FindOps.java	Tue Apr 23 11:13:38 2013 +0100
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2012, 2013, 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;
+
+import java.util.Optional;
+import java.util.OptionalDouble;
+import java.util.OptionalInt;
+import java.util.OptionalLong;
+import java.util.Spliterator;
+import java.util.concurrent.CountedCompleter;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+
+/**
+ * Factory for instances of a short-circuiting {@code TerminalOp} that searches
+ * for an element in a stream pipeline, and terminates when it finds one.
+ * Supported variants include find-first (find the first element in the
+ * encounter order) and find-any (find any element, may not be the first in
+ * encounter order.)
+ *
+ * @since 1.8
+ */
+final class FindOps {
+
+    private FindOps() { }
+
+    /**
+     * Constructs a {@code TerminalOp} for streams of objects.
+     *
+     * @param <T> the type of elements of the stream
+     * @param mustFindFirst whether the {@code TerminalOp} must produce the
+     *        first element in the encounter order
+     * @return a {@code TerminalOp} implementing the find operation
+     */
+    public static <T> TerminalOp<T, Optional<T>> makeRef(boolean mustFindFirst) {
+        return new FindOp<>(mustFindFirst, StreamShape.REFERENCE, Optional.empty(),
+                            Optional::isPresent, FindSink.OfRef::new);
+    }
+
+    /**
+     * Constructs a {@code TerminalOp} for streams of ints.
+     *
+     * @param mustFindFirst whether the {@code TerminalOp} must produce the
+     *        first element in the encounter order
+     * @return a {@code TerminalOp} implementing the find operation
+     */
+    public static TerminalOp<Integer, OptionalInt> makeInt(boolean mustFindFirst) {
+        return new FindOp<>(mustFindFirst, StreamShape.INT_VALUE, OptionalInt.empty(),
+                            OptionalInt::isPresent, FindSink.OfInt::new);
+    }
+
+    /**
+     * Constructs a {@code TerminalOp} for streams of longs.
+     *
+     * @param mustFindFirst whether the {@code TerminalOp} must produce the
+     *        first element in the encounter order
+     * @return a {@code TerminalOp} implementing the find operation
+     */
+    public static TerminalOp<Long, OptionalLong> makeLong(boolean mustFindFirst) {
+        return new FindOp<>(mustFindFirst, StreamShape.LONG_VALUE, OptionalLong.empty(),
+                            OptionalLong::isPresent, FindSink.OfLong::new);
+    }
+
+    /**
+     * Constructs a {@code FindOp} for streams of doubles.
+     *
+     * @param mustFindFirst whether the {@code TerminalOp} must produce the
+     *        first element in the encounter order
+     * @return a {@code TerminalOp} implementing the find operation
+     */
+    public static TerminalOp<Double, OptionalDouble> makeDouble(boolean mustFindFirst) {
+        return new FindOp<>(mustFindFirst, StreamShape.DOUBLE_VALUE, OptionalDouble.empty(),
+                            OptionalDouble::isPresent, FindSink.OfDouble::new);
+    }
+
+    /**
+     * A short-circuiting {@code TerminalOp} that searches for an element in a
+     * stream pipeline, and terminates when it finds one.  Implements both
+     * find-first (find the first element in the encounter order) and find-any
+     * (find any element, may not be the first in encounter order.)
+     *
+     * @param <T> the output type of the stream pipeline
+     * @param <O> the result type of the find operation, typically an optional
+     *        type
+     */
+    private static final class FindOp<T, O> implements TerminalOp<T, O> {
+        private final StreamShape shape;
+        final boolean mustFindFirst;
+        final O emptyValue;
+        final Predicate<O> presentPredicate;
+        final Supplier<TerminalSink<T, O>> sinkSupplier;
+
+        /**
+         * Constructs a {@code FindOp}.
+         *
+         * @param mustFindFirst if true, must find the first element in
+         *        encounter order, otherwise can find any element
+         * @param shape stream shape of elements to search
+         * @param emptyValue result value corresponding to "found nothing"
+         * @param presentPredicate {@code Predicate} on result value
+         *        corresponding to "found something"
+         * @param sinkSupplier supplier for a {@code TerminalSink} implementing
+         *        the matching functionality
+         */
+        FindOp(boolean mustFindFirst,
+                       StreamShape shape,
+                       O emptyValue,
+                       Predicate<O> presentPredicate,
+                       Supplier<TerminalSink<T, O>> sinkSupplier) {
+            this.mustFindFirst = mustFindFirst;
+            this.shape = shape;
+            this.emptyValue = emptyValue;
+            this.presentPredicate = presentPredicate;
+            this.sinkSupplier = sinkSupplier;
+        }
+
+        @Override
+        public int getOpFlags() {
+            return StreamOpFlag.IS_SHORT_CIRCUIT | (mustFindFirst ? 0 : StreamOpFlag.NOT_ORDERED);
+        }
+
+        @Override
+        public StreamShape inputShape() {
+            return shape;
+        }
+
+        @Override
+        public <S> O evaluateSequential(PipelineHelper<T> helper,
+                                        Spliterator<S> spliterator) {
+            O result = helper.wrapAndCopyInto(sinkSupplier.get(), spliterator).get();
+            return result != null ? result : emptyValue;
+        }
+
+        @Override
+        public <P_IN> O evaluateParallel(PipelineHelper<T> helper,
+                                         Spliterator<P_IN> spliterator) {
+            return new FindTask<>(this, helper, spliterator).invoke();
+        }
+    }
+
+    /**
+     * Implementation of @{code TerminalSink} that implements the find
+     * functionality, requesting cancellation when something has been found
+     *
+     * @param <T> The type of input element
+     * @param <O> The result type, typically an optional type
+     */
+    private static abstract class FindSink<T, O> implements TerminalSink<T, O> {
+        boolean hasValue;
+        T value;
+
+        FindSink() {} // Avoid creation of special accessor
+
+        @Override
+        public void accept(T value) {
+            if (!hasValue) {
+                hasValue = true;
+                this.value = value;
+            }
+        }
+
+        @Override
+        public boolean cancellationRequested() {
+            return hasValue;
+        }
+
+        /** Specialization of {@code FindSink} for reference streams */
+        static final class OfRef<T> extends FindSink<T, Optional<T>> {
+            @Override
+            public Optional<T> get() {
+                return hasValue ? Optional.of(value) : null;
+            }
+        }
+
+        /** Specialization of {@code FindSink} for int streams */
+        static final class OfInt extends FindSink<Integer, OptionalInt>
+                implements Sink.OfInt {
+            @Override
+            public void accept(int value) {
+                // Boxing is OK here, since few values will actually flow into the sink
+                accept((Integer) value);
+            }
+
+            @Override
+            public OptionalInt get() {
+                return hasValue ? OptionalInt.of(value) : null;
+            }
+        }
+
+        /** Specialization of {@code FindSink} for long streams */
+        static final class OfLong extends FindSink<Long, OptionalLong>
+                implements Sink.OfLong {
+            @Override
+            public void accept(long value) {
+                // Boxing is OK here, since few values will actually flow into the sink
+                accept((Long) value);
+            }
+
+            @Override
+            public OptionalLong get() {
+                return hasValue ? OptionalLong.of(value) : null;
+            }
+        }
+
+        /** Specialization of {@code FindSink} for double streams */
+        static final class OfDouble extends FindSink<Double, OptionalDouble>
+                implements Sink.OfDouble {
+            @Override
+            public void accept(double value) {
+                // Boxing is OK here, since few values will actually flow into the sink
+                accept((Double) value);
+            }
+
+            @Override
+            public OptionalDouble get() {
+                return hasValue ? OptionalDouble.of(value) : null;
+            }
+        }
+    }
+
+    /**
+     * {@code ForkJoinTask} implementing parallel short-circuiting search
+     * @param <P_IN> Input element type to the stream pipeline
+     * @param <P_OUT> Output element type from the stream pipeline
+     * @param <O> Result type from the find operation
+     */
+    private static final class FindTask<P_IN, P_OUT, O>
+            extends AbstractShortCircuitTask<P_IN, P_OUT, O, FindTask<P_IN, P_OUT, O>> {
+        private final FindOp<P_OUT, O> op;
+
+        FindTask(FindOp<P_OUT, O> op,
+                 PipelineHelper<P_OUT> helper,
+                 Spliterator<P_IN> spliterator) {
+            super(helper, spliterator);
+            this.op = op;
+        }
+
+        FindTask(FindTask<P_IN, P_OUT, O> parent, Spliterator<P_IN> spliterator) {
+            super(parent, spliterator);
+            this.op = parent.op;
+        }
+
+        @Override
+        protected FindTask<P_IN, P_OUT, O> makeChild(Spliterator<P_IN> spliterator) {
+            return new FindTask<>(this, spliterator);
+        }
+
+        @Override
+        protected O getEmptyResult() {
+            return op.emptyValue;
+        }
+
+        private void foundResult(O answer) {
+            if (isLeftmostNode())
+                shortCircuit(answer);
+            else
+                cancelLaterNodes();
+        }
+
+        @Override
+        protected O doLeaf() {
+            O result = helper.wrapAndCopyInto(op.sinkSupplier.get(), spliterator).get();
+            if (!op.mustFindFirst) {
+                if (result != null)
+                    shortCircuit(result);
+                return null;
+            }
+            else {
+                if (result != null) {
+                    foundResult(result);
+                    return result;
+                }
+                else
+                    return null;
+            }
+        }
+
+        @Override
+        public void onCompletion(CountedCompleter<?> caller) {
+            if (op.mustFindFirst) {
+                    for (FindTask<P_IN, P_OUT, O> child = leftChild, p = null; child != p;
+                         p = child, child = rightChild) {
+                    O result = child.getLocalResult();
+                    if (result != null && op.presentPredicate.test(result)) {
+                        setLocalResult(result);
+                        foundResult(result);
+                        break;
+                    }
+                }
+            }
+            super.onCompletion(caller);
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/util/stream/ForEachOps.java	Tue Apr 23 11:13:38 2013 +0100
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 2012, 2013, 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;
+
+import java.util.Objects;
+import java.util.Spliterator;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountedCompleter;
+import java.util.function.Consumer;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+
+/**
+ * Factory for creating instances of {@code TerminalOp} that perform an
+ * action for every element of a stream.  Supported variants include unordered
+ * traversal (elements are provided to the {@code Consumer} as soon as they are
+ * available), and ordered traversal (elements are provided to the
+ * {@code Consumer} in encounter order.)
+ *
+ * <p>Elements are provided to the {@code Consumer} on whatever thread and
+ * whatever order they become available.  For ordered traversals, it is
+ * guaranteed that processing an element <em>happens-before</em> processing
+ * subsequent elements in the encounter order.
+ *
+ * <p>Exceptions occurring as a result of sending an element to the
+ * {@code Consumer} will be relayed to the caller and traversal will be
+ * prematurely terminated.
+ *
+ * @since 1.8
+ */
+final class ForEachOps {
+
+    private ForEachOps() { }
+
+    /**
+     * Constructs a {@code TerminalOp} that perform an action for every element
+     * of a stream.
+     *
+     * @param action the {@code Consumer} that receives all elements of a
+     *        stream
+     * @param ordered whether an ordered traversal is requested
+     * @param <T> the type of the stream elements
+     * @return the {@code TerminalOp} instance
+     */
+    public static <T> TerminalOp<T, Void> makeRef(Consumer<? super T> action,
+                                                  boolean ordered) {
+        Objects.requireNonNull(action);
+        return new ForEachOp.OfRef<>(action, ordered);
+    }
+
+    /**
+     * Constructs a {@code TerminalOp} that perform an action for every element
+     * of an {@code IntStream}.
+     *
+     * @param action the {@code IntConsumer} that receives all elements of a
+     *        stream
+     * @param ordered whether an ordered traversal is requested
+     * @return the {@code TerminalOp} instance
+     */
+    public static TerminalOp<Integer, Void> makeInt(IntConsumer action,
+                                                    boolean ordered) {
+        Objects.requireNonNull(action);
+        return new ForEachOp.OfInt(action, ordered);
+    }
+
+    /**
+     * Constructs a {@code TerminalOp} that perform an action for every element
+     * of a {@code LongStream}.
+     *
+     * @param action the {@code LongConsumer} that receives all elements of a
+     *        stream
+     * @param ordered whether an ordered traversal is requested
+     * @return the {@code TerminalOp} instance
+     */
+    public static TerminalOp<Long, Void> makeLong(LongConsumer action,
+                                                  boolean ordered) {
+        Objects.requireNonNull(action);
+        return new ForEachOp.OfLong(action, ordered);
+    }
+
+    /**
+     * Constructs a {@code TerminalOp} that perform an action for every element
+     * of a {@code DoubleStream}.
+     *
+     * @param action the {@code DoubleConsumer} that receives all elements of
+     *        a stream
+     * @param ordered whether an ordered traversal is requested
+     * @return the {@code TerminalOp} instance
+     */
+    public static TerminalOp<Double, Void> makeDouble(DoubleConsumer action,
+                                                      boolean ordered) {
+        Objects.requireNonNull(action);
+        return new ForEachOp.OfDouble(action, ordered);
+    }
+
+    /**
+     * A {@code TerminalOp} that evaluates a stream pipeline and sends the
+     * output to itself as a {@code TerminalSink}.  Elements will be sent in
+     * whatever thread they become available.  If the traversal is unordered,
+     * they will be sent independent of the stream's encounter order.
+     *
+     * <p>This terminal operation is stateless.  For parallel evaluation, each
+     * leaf instance of a {@code ForEachTask} will send elements to the same
+     * {@code TerminalSink} reference that is an instance of this class.
+     *
+     * @param <T> the output type of the stream pipeline
+     */
+    private static abstract class ForEachOp<T>
+            implements TerminalOp<T, Void>, TerminalSink<T, Void> {
+        private final boolean ordered;
+
+        protected ForEachOp(boolean ordered) {
+            this.ordered = ordered;
+        }
+
+        // TerminalOp
+
+        @Override
+        public int getOpFlags() {
+            return ordered ? 0 : StreamOpFlag.NOT_ORDERED;
+        }
+
+        @Override
+        public <S> Void evaluateSequential(PipelineHelper<T> helper,
+                                           Spliterator<S> spliterator) {
+            return helper.wrapAndCopyInto(this, spliterator).get();
+        }
+
+        @Override
+        public <S> Void evaluateParallel(PipelineHelper<T> helper,
+                                         Spliterator<S> spliterator) {
+            if (ordered)
+                new ForEachOrderedTask<>(helper, spliterator, this).invoke();
+            else
+                new ForEachTask<>(helper, spliterator, helper.wrapSink(this)).invoke();
+            return null;
+        }
+
+        // TerminalSink
+
+        @Override
+        public Void get() {
+            return null;
+        }
+
+        // Implementations
+
+        /** Implementation class for reference streams */
+        private static class OfRef<T> extends ForEachOp<T> {
+            final Consumer<? super T> consumer;
+
+            OfRef(Consumer<? super T> consumer, boolean ordered) {
+                super(ordered);
+                this.consumer = consumer;
+            }
+
+            @Override
+            public void accept(T t) {
+                consumer.accept(t);
+            }
+        }
+
+        /** Implementation class for {@code IntStream} */
+        private static class OfInt extends ForEachOp<Integer>
+                implements Sink.OfInt {
+            final IntConsumer consumer;
+
+            OfInt(IntConsumer consumer, boolean ordered) {
+                super(ordered);
+                this.consumer = consumer;
+            }
+
+            @Override
+            public StreamShape inputShape() {
+                return StreamShape.INT_VALUE;
+            }
+
+            @Override
+            public void accept(int t) {
+                consumer.accept(t);
+            }
+        }
+
+        /** Implementation class for {@code LongStream} */
+        private static class OfLong extends ForEachOp<Long>
+                implements Sink.OfLong {
+            final LongConsumer consumer;
+
+            OfLong(LongConsumer consumer, boolean ordered) {
+                super(ordered);
+                this.consumer = consumer;
+            }
+
+            @Override
+            public StreamShape inputShape() {
+                return StreamShape.LONG_VALUE;
+            }
+
+            @Override
+            public void accept(long t) {
+                consumer.accept(t);
+            }
+        }
+
+        /** Implementation class for {@code DoubleStream} */
+        private static class OfDouble extends ForEachOp<Double>
+                implements Sink.OfDouble {
+            final DoubleConsumer consumer;
+
+            OfDouble(DoubleConsumer consumer, boolean ordered) {
+                super(ordered);
+                this.consumer = consumer;
+            }
+
+            @Override
+            public StreamShape inputShape() {
+                return StreamShape.DOUBLE_VALUE;
+            }
+
+            @Override
+            public void accept(double t) {
+                consumer.accept(t);
+            }
+        }
+    }
+
+    /** A {@code ForkJoinTask} for performing a parallel for-each operation */
+    private static class ForEachTask<S, T> extends CountedCompleter<Void> {
+        private Spliterator<S> spliterator;
+        private final Sink<S> sink;
+        private final PipelineHelper<T> helper;
+        private final long targetSize;
+
+        ForEachTask(PipelineHelper<T> helper,
+                    Spliterator<S> spliterator,
+                    Sink<S> sink) {
+            super(null);
+            this.spliterator = spliterator;
+            this.sink = sink;
+            this.targetSize = AbstractTask.suggestTargetSize(spliterator.estimateSize());
+            this.helper = helper;
+        }
+
+        ForEachTask(ForEachTask<S, T> parent, Spliterator<S> spliterator) {
+            super(parent);
+            this.spliterator = spliterator;
+            this.sink = parent.sink;
+            this.targetSize = parent.targetSize;
+            this.helper = parent.helper;
+        }
+
+        public void compute() {
+            boolean isShortCircuit = StreamOpFlag.SHORT_CIRCUIT.isKnown(helper.getStreamAndOpFlags());
+            while (true) {
+                if (isShortCircuit && sink.cancellationRequested()) {
+                    propagateCompletion();
+                    spliterator = null;
+                    return;
+                }
+
+                Spliterator<S> split;
+                if (!AbstractTask.suggestSplit(spliterator, targetSize)
+                    || (split = spliterator.trySplit()) == null) {
+                    helper.copyInto(sink, spliterator);
+                    propagateCompletion();
+                    spliterator = null;
+                    return;
+                }
+                else {
+                    addToPendingCount(1);
+                    new ForEachTask<>(this, split).fork();
+                }
+            }
+        }
+    }
+
+    /**
+     * A {@code ForkJoinTask} for performing a parallel for-each operation
+     * which visits the elements in encounter order
+     */
+    private static class ForEachOrderedTask<S, T> extends CountedCompleter<Void> {
+        private final PipelineHelper<T> helper;
+        private Spliterator<S> spliterator;
+        private final long targetSize;
+        private final ConcurrentHashMap<ForEachOrderedTask<S, T>, ForEachOrderedTask<S, T>> completionMap;
+        private final Sink<T> action;
+        private final Object lock;
+        private final ForEachOrderedTask<S, T> leftPredecessor;
+        private Node<T> node;
+
+        protected ForEachOrderedTask(PipelineHelper<T> helper,
+                                     Spliterator<S> spliterator,
+                                     Sink<T> action) {
+            super(null);
+            this.helper = helper;
+            this.spliterator = spliterator;
+            this.targetSize = AbstractTask.suggestTargetSize(spliterator.estimateSize());
+            this.completionMap = new ConcurrentHashMap<>();
+            this.action = action;
+            this.lock = new Object();
+            this.leftPredecessor = null;
+        }
+
+        ForEachOrderedTask(ForEachOrderedTask<S, T> parent,
+                           Spliterator<S> spliterator,
+                           ForEachOrderedTask<S, T> leftPredecessor) {
+            super(parent);
+            this.helper = parent.helper;
+            this.spliterator = spliterator;
+            this.targetSize = parent.targetSize;
+            this.completionMap = parent.completionMap;
+            this.action = parent.action;
+            this.lock = parent.lock;
+            this.leftPredecessor = leftPredecessor;
+        }
+
+        @Override
+        public final void compute() {
+            doCompute(this);
+        }
+
+        private static<S, T> void doCompute(ForEachOrderedTask<S, T> task) {
+            while (true) {
+                Spliterator<S> split;
+                if (!AbstractTask.suggestSplit(task.spliterator, task.targetSize)
+                    || (split = task.spliterator.trySplit()) == null) {
+                    if (task.getPendingCount() == 0) {
+                        task.helper.wrapAndCopyInto(task.action, task.spliterator);
+                    }
+                    else {
+                        Node.Builder<T> nb = task.helper.makeNodeBuilder(
+                                task.helper.exactOutputSizeIfKnown(task.spliterator),
+                                size -> (T[]) new Object[size]);
+                        task.node = task.helper.wrapAndCopyInto(nb, task.spliterator).build();
+                    }
+                    task.tryComplete();
+                    return;
+                }
+                else {
+                    ForEachOrderedTask<S, T> leftChild = new ForEachOrderedTask<>(task, split, task.leftPredecessor);
+                    ForEachOrderedTask<S, T> rightChild = new ForEachOrderedTask<>(task, task.spliterator, leftChild);
+                    task.completionMap.put(leftChild, rightChild);
+                    task.addToPendingCount(1); // forking
+                    rightChild.addToPendingCount(1); // right pending on left child
+                    if (task.leftPredecessor != null) {
+                        leftChild.addToPendingCount(1); // left pending on previous subtree, except left spine
+                        if (task.completionMap.replace(task.leftPredecessor, task, leftChild))
+                            task.addToPendingCount(-1);      // transfer my "right child" count to my left child
+                        else
+                            leftChild.addToPendingCount(-1); // left child is ready to go when ready
+                    }
+                    leftChild.fork();
+                    task = rightChild;
+                }
+            }
+        }
+
+        @Override
+        public void onCompletion(CountedCompleter<?> caller) {
+            spliterator = null;
+            if (node != null) {
+                // Dump any data from this leaf into the sink
+                synchronized (lock) {
+                    node.forEach(action);
+                }
+                node = null;
+            }
+            ForEachOrderedTask<S, T> victim = completionMap.remove(this);
+            if (victim != null)
+                victim.tryComplete();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/util/stream/IntStream.java	Tue Apr 23 11:13:38 2013 +0100
@@ -0,0 +1,655 @@
+/*
+ * Copyright (c) 2012, 2013, 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;
+
+import java.util.IntSummaryStatistics;
+import java.util.OptionalDouble;
+import java.util.OptionalInt;
+import java.util.PrimitiveIterator;
+import java.util.Spliterator;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+import java.util.function.IntBinaryOperator;
+import java.util.function.IntConsumer;
+import java.util.function.IntFunction;
+import java.util.function.IntPredicate;
+import java.util.function.IntToDoubleFunction;
+import java.util.function.IntToLongFunction;
+import java.util.function.IntUnaryOperator;
+import java.util.function.ObjIntConsumer;
+import java.util.function.Supplier;
+
+/**
+ * A sequence of primitive integer elements supporting sequential and parallel
+ * bulk operations. Streams support lazy intermediate operations (transforming
+ * a stream to another stream) such as {@code filter} and {@code map}, and terminal
+ * operations (consuming the contents of a stream to produce a result or
+ * side-effect), such as {@code forEach}, {@code findFirst}, and {@code
+ * iterator}.  Once an operation has been performed on a stream, it
+ * is considered <em>consumed</em> and no longer usable for other operations.
+ *
+ * <p>For sequential stream pipelines, all operations are performed in the
+ * <a href="package-summary.html#Ordering">encounter order</a> of the pipeline
+ * source, if the pipeline source has a defined encounter order.
+ *
+ * <p>For parallel stream pipelines, unless otherwise specified, intermediate
+ * stream operations preserve the <a href="package-summary.html#Ordering">
+ * encounter order</a> of their source, and terminal operations
+ * respect the encounter order of their source, if the source
+ * has an encounter order.  Provided that and parameters to stream operations
+ * satisfy the <a href="package-summary.html#NonInterference">non-interference
+ * requirements</a>, and excepting differences arising from the absence of
+ * a defined encounter order, the result of a stream pipeline should be the
+ * stable across multiple executions of the same operations on the same source.
+ * However, the timing and thread in which side-effects occur (for those
+ * operations which are allowed to produce side-effects, such as
+ * {@link #forEach(IntConsumer)}), are explicitly nondeterministic for parallel
+ * execution of stream pipelines.
+ *
+ * <p>Unless otherwise noted, passing a {@code null} argument to any stream
+ * method may result in a {@link NullPointerException}.
+ *
+ * @apiNote
+ * Streams are not data structures; they do not manage the storage for their
+ * elements, nor do they support access to individual elements.  However,
+ * you can use the {@link #iterator()} or {@link #spliterator()} operations to
+ * perform a controlled traversal.
+ *
+ * @since 1.8
+ * @see <a href="package-summary.html">java.util.stream</a>
+ */
+public interface IntStream extends BaseStream<Integer, IntStream> {
+
+    /**
+     * Returns a stream consisting of the elements of this stream that match
+     * the given predicate.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param predicate a <a href="package-summary.html#NonInterference">
+     *                  non-interfering, stateless</a> predicate to apply to
+     *                  each element to determine if it should be included
+     * @return the new stream
+     */
+    IntStream filter(IntPredicate predicate);
+
+    /**
+     * Returns a stream consisting of the results of applying the given
+     * function to the elements of this stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to each
+     *               element
+     * @return the new stream
+     */
+    IntStream map(IntUnaryOperator mapper);
+
+    /**
+     * Returns an object-valued {@code Stream} consisting of the results of
+     * applying the given function to the elements of this stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">
+     *     intermediate operation</a>.
+     *
+     * @param <U> the element type of the new stream
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to each
+     *               element
+     * @return the new stream
+     */
+    <U> Stream<U> mapToObj(IntFunction<? extends U> mapper);
+
+    /**
+     * Returns a {@code LongStream} consisting of the results of applying the
+     * given function to the elements of this stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to each
+     *               element
+     * @return the new stream
+     */
+    LongStream mapToLong(IntToLongFunction mapper);
+
+    /**
+     * Returns a {@code DoubleStream} consisting of the results of applying the
+     * given function to the elements of this stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to each
+     *               element
+     * @return the new stream
+     */
+    DoubleStream mapToDouble(IntToDoubleFunction mapper);
+
+    /**
+     * Returns a stream consisting of the results of replacing each element of
+     * this stream with the contents of the stream produced by applying the
+     * provided mapping function to each element.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @apiNote
+     * The {@code flatMap()} operation has the effect of applying a one-to-many
+     * tranformation to the elements of the stream, and then flattening the
+     * resulting elements into a new stream. For example, if {@code orders}
+     * is a stream of purchase orders, and each purchase order contains a
+     * collection of line items, then the following produces a stream of line
+     * items:
+     * <pre>{@code
+     *     orderStream.flatMap(order -> order.getLineItems().stream())...
+     * }</pre>
+     *
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to
+     *               each element which produces an {@code IntStream} of new
+     *               values
+     * @return the new stream
+     * @see Stream#flatMap(Function)
+     */
+    IntStream flatMap(IntFunction<? extends IntStream> mapper);
+
+    /**
+     * Returns a stream consisting of the distinct elements of this stream.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">stateful
+     * intermediate operation</a>.
+     *
+     * @return the new stream
+     */
+    IntStream distinct();
+
+    /**
+     * Returns a stream consisting of the elements of this stream in sorted
+     * order.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">stateful
+     * intermediate operation</a>.
+     *
+     * @return the new stream
+     */
+    IntStream sorted();
+
+    /**
+     * Returns a stream consisting of the elements of this stream, additionally
+     * performing the provided action on each element as elements are consumed
+     * from the resulting stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * <p>For parallel stream pipelines, the action may be called at
+     * whatever time and in whatever thread the element is made available by the
+     * upstream operation.  If the action modifies shared state,
+     * it is responsible for providing the required synchronization.
+     *
+     * @apiNote This method exists mainly to support debugging, where you want
+     * to see the elements as they flow past a certain point in a pipeline:
+     * <pre>{@code
+     *     list.stream()
+     *         .filter(filteringFunction)
+     *         .peek(e -> {System.out.println("Filtered value: " + e); });
+     *         .map(mappingFunction)
+     *         .peek(e -> {System.out.println("Mapped value: " + e); });
+     *         .collect(Collectors.toIntSummaryStastistics());
+     * }</pre>
+     *
+     * @param consumer a <a href="package-summary.html#NonInterference">
+     *                 non-interfering</a> action to perform on the elements as
+     *                 they are consumed from the stream
+     * @return the new stream
+     */
+    IntStream peek(IntConsumer consumer);
+
+    /**
+     * Returns a stream consisting of the elements of this stream, truncated
+     * to be no longer than {@code maxSize} in length.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * stateful intermediate operation</a>.
+     *
+     * @param maxSize the number of elements the stream should be limited to
+     * @return the new stream
+     * @throws IllegalArgumentException if {@code maxSize} is negative
+     */
+    IntStream limit(long maxSize);
+
+    /**
+     * Returns a stream consisting of the remaining elements of this stream
+     * after indexing {@code startInclusive} elements into the stream. If the
+     * {@code startInclusive} index lies past the end of this stream then an
+     * empty stream will be returned.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">stateful
+     * intermediate operation</a>.
+     *
+     * @param startInclusive the number of leading elements to skip
+     * @return the new stream
+     * @throws IllegalArgumentException if {@code startInclusive} is negative
+     */
+    IntStream substream(long startInclusive);
+
+    /**
+     * Returns a stream consisting of the remaining elements of this stream
+     * after indexing {@code startInclusive} elements into the stream and
+     * truncated to contain no more than {@code endExclusive - startInclusive}
+     * elements. If the {@code startInclusive} index lies past the end
+     * of this stream then an empty stream will be returned.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * stateful intermediate operation</a>.
+     *
+     * @param startInclusive the starting position of the substream, inclusive
+     * @param endExclusive the ending position of the substream, exclusive
+     * @return the new stream
+     * @throws IllegalArgumentException if {@code startInclusive} or
+     * {@code endExclusive} is negative or {@code startInclusive} is greater
+     * than {@code endExclusive}
+     */
+    IntStream substream(long startInclusive, long endExclusive);
+
+    /**
+     * Performs an action for each element of this stream.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * <p>For parallel stream pipelines, this operation does <em>not</em>
+     * guarantee to respect the encounter order of the stream, as doing so
+     * would sacrifice the benefit of parallelism.  For any given element, the
+     * action may be performed at whatever time and in whatever thread the
+     * library chooses.  If the action accesses shared state, it is
+     * responsible for providing the required synchronization.
+     *
+     * @param action a <a href="package-summary.html#NonInterference">
+     *               non-interfering</a> action to perform on the elements
+     */
+    void forEach(IntConsumer action);
+
+    /**
+     * Performs an action for each element of this stream, guaranteeing that
+     * each element is processed in encounter order for streams that have a
+     * defined encounter order.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @param action a <a href="package-summary.html#NonInterference">
+     *               non-interfering</a> action to perform on the elements
+     * @see #forEach(IntConsumer)
+     */
+    void forEachOrdered(IntConsumer action);
+
+    /**
+     * Returns an array containing the elements of this stream.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @return an array containing the elements of this stream
+     */
+    int[] toArray();
+
+    /**
+     * Performs a <a href="package-summary.html#Reduction">reduction</a> on the
+     * elements of this stream, using the provided identity value and an
+     * <a href="package-summary.html#Associativity">associative</a>
+     * accumulation function, and returns the reduced value.  This is equivalent
+     * to:
+     * <pre>{@code
+     *     int result = identity;
+     *     for (int element : this stream)
+     *         result = accumulator.apply(result, element)
+     *     return result;
+     * }</pre>
+     *
+     * but is not constrained to execute sequentially.
+     *
+     * <p>The {@code identity} value must be an identity for the accumulator
+     * function. This means that for all {@code x},
+     * {@code accumulator.apply(identity, x)} is equal to {@code x}.
+     * The {@code accumulator} function must be an
+     * <a href="package-summary.html#Associativity">associative</a> function.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @apiNote Sum, min, max, and average are all special cases of reduction.
+     * Summing a stream of numbers can be expressed as:
+     *
+     * <pre>{@code
+     *     int sum = integers.reduce(0, (a, b) -> a+b);
+     * }</pre>
+     *
+     * or more compactly:
+     *
+     * <pre>{@code
+     *     int sum = integers.reduce(0, Integer::sum);
+     * }</pre>
+     *
+     * <p>While this may seem a more roundabout way to perform an aggregation
+     * compared to simply mutating a running total in a loop, reduction
+     * operations parallelize more gracefully, without needing additional
+     * synchronization and with greatly reduced risk of data races.
+     *
+     * @param identity the identity value for the accumulating function
+     * @param op an <a href="package-summary.html#Associativity">associative</a>
+     *                    <a href="package-summary.html#NonInterference">non-interfering,
+     *                    stateless</a> function for combining two values
+     * @return the result of the reduction
+     * @see #sum()
+     * @see #min()
+     * @see #max()
+     * @see #average()
+     */
+    int reduce(int identity, IntBinaryOperator op);
+
+    /**
+     * Performs a <a href="package-summary.html#Reduction">reduction</a> on the
+     * elements of this stream, using an
+     * <a href="package-summary.html#Associativity">associative</a> accumulation
+     * function, and returns an {@code OptionalInt} describing the reduced value,
+     * if any. This is equivalent to:
+     * <pre>{@code
+     *     boolean foundAny = false;
+     *     int result = null;
+     *     for (int element : this stream) {
+     *         if (!foundAny) {
+     *             foundAny = true;
+     *             result = element;
+     *         }
+     *         else
+     *             result = accumulator.apply(result, element);
+     *     }
+     *     return foundAny ? OptionalInt.of(result) : OptionalInt.empty();
+     * }</pre>
+     *
+     * but is not constrained to execute sequentially.
+     *
+     * <p>The {@code accumulator} function must be an
+     * <a href="package-summary.html#Associativity">associative</a> function.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @param op an <a href="package-summary.html#Associativity">associative</a>
+     *           <a href="package-summary.html#NonInterference">non-interfering,
+     *           stateless</a> function for combining two values
+     * @return the result of the reduction
+     * @see #reduce(int, IntBinaryOperator)
+     */
+    OptionalInt reduce(IntBinaryOperator op);
+
+    /**
+     * Performs a <a href="package-summary.html#MutableReduction">mutable
+     * reduction</a> operation on the elements of this stream.  A mutable
+     * reduction is one in which the reduced value is a mutable value holder,
+     * such as an {@code ArrayList}, and elements are incorporated by updating
+     * the state of the result, rather than by replacing the result.  This
+     * produces a result equivalent to:
+     * <pre>{@code
+     *     R result = resultFactory.get();
+     *     for (int element : this stream)
+     *         accumulator.accept(result, element);
+     *     return result;
+     * }</pre>
+     *
+     * <p>Like {@link #reduce(int, IntBinaryOperator)}, {@code collect} operations
+     * can be parallelized without requiring additional synchronization.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @param <R> type of the result
+     * @param resultFactory a function that creates a new result container.
+     *                      For a parallel execution, this function may be
+     *                      called multiple times and must return a fresh value
+     *                      each time.
+     * @param accumulator an <a href="package-summary.html#Associativity">associative</a>
+     *                    <a href="package-summary.html#NonInterference">non-interfering,
+     *                    stateless</a> function for incorporating an additional
+     *                    element into a result
+     * @param combiner an <a href="package-summary.html#Associativity">associative</a>
+     *                 <a href="package-summary.html#NonInterference">non-interfering,
+     *                 stateless</a> function for combining two values, which
+     *                 must be compatible with the accumulator function
+     * @return the result of the reduction
+     * @see Stream#collect(Supplier, BiConsumer, BiConsumer)
+     */
+    <R> R collect(Supplier<R> resultFactory,
+                  ObjIntConsumer<R> accumulator,
+                  BiConsumer<R, R> combiner);
+
+    /**
+     * Returns the sum of elements in this stream.  This is a special case
+     * of a <a href="package-summary.html#MutableReduction">reduction</a>
+     * and is equivalent to:
+     * <pre>{@code
+     *     return reduce(0, Integer::sum);
+     * }</pre>
+     *
+     * @return the sum of elements in this stream
+     */
+    int sum();
+
+    /**
+     * Returns an {@code OptionalInt} describing the minimum element of this
+     * stream, or an empty optional if this stream is empty.  This is a special
+     * case of a <a href="package-summary.html#MutableReduction">reduction</a>
+     * and is equivalent to:
+     * <pre>{@code
+     *     return reduce(Integer::min);
+     * }</pre>
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>.
+     *
+
+     * @return an {@code OptionalInt} containing the minimum element of this
+     * stream, or an empty {@code OptionalInt} if the stream is empty
+     */
+    OptionalInt min();
+
+    /**
+     * Returns an {@code OptionalInt} describing the maximum element of this
+     * stream, or an empty optional if this stream is empty.  This is a special
+     * case of a <a href="package-summary.html#MutableReduction">reduction</a>
+     * and is equivalent to:
+     * <pre>{@code
+     *     return reduce(Integer::max);
+     * }</pre>
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @return an {@code OptionalInt} containing the maximum element of this
+     * stream, or an empty {@code OptionalInt} if the stream is empty
+     */
+    OptionalInt max();
+
+    /**
+     * Returns the count of elements in this stream.  This is a special case of
+     * a <a href="package-summary.html#MutableReduction">reduction</a> and is
+     * equivalent to:
+     * <pre>{@code
+     *     return mapToLong(e -> 1L).sum();
+     * }</pre>
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>.
+     *
+     * @return the count of elements in this stream
+     */
+    long count();
+
+    /**
+     * Returns an {@code OptionalDouble} describing the average of elements of
+     * this stream, or an empty optional if this stream is empty.  This is a
+     * special case of a
+     * <a href="package-summary.html#MutableReduction">reduction</a>.
+     *
+     * @return an {@code OptionalDouble} containing the average element of this
+     * stream, or an empty optional if the stream is empty
+     */
+    OptionalDouble average();
+
+    /**
+     * Returns an {@code IntSummaryStatistics} describing various
+     * summary data about the elements of this stream.  This is a special
+     * case of a <a href="package-summary.html#MutableReduction">reduction</a>.
+     *
+     * @return an {@code IntSummaryStatistics} describing various summary data
+     * about the elements of this stream
+     */
+    IntSummaryStatistics summaryStatistics();
+
+    /**
+     * Returns whether any elements of this stream match the provided
+     * predicate.  May not evaluate the predicate on all elements if not
+     * necessary for determining the result.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * terminal operation</a>.
+     *
+     * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
+     *                  stateless</a> predicate to apply to elements of this
+     *                  stream
+     * @return {@code true} if any elements of the stream match the provided
+     * predicate otherwise {@code false}
+     */
+    boolean anyMatch(IntPredicate predicate);
+
+    /**
+     * Returns whether all elements of this stream match the provided predicate.
+     * May not evaluate the predicate on all elements if not necessary for
+     * determining the result.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * terminal operation</a>.
+     *
+     * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
+     *                  stateless</a> predicate to apply to elements of this
+     *                  stream
+     * @return {@code true} if all elements of the stream match the provided
+     * predicate otherwise {@code false}
+     */
+    boolean allMatch(IntPredicate predicate);
+
+    /**
+     * Returns whether no elements of this stream match the provided predicate.
+     * May not evaluate the predicate on all elements if not necessary for
+     * determining the result.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * terminal operation</a>.
+     *
+     * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
+     *                  stateless</a> predicate to apply to elements of this
+     *                  stream
+     * @return {@code true} if no elements of the stream match the provided
+     * predicate otherwise {@code false}
+     */
+    boolean noneMatch(IntPredicate predicate);
+
+    /**
+     * Returns an {@link OptionalInt} describing the first element of this
+     * stream (in the encounter order), or an empty {@code OptionalInt} if the
+     * stream is empty.  If the stream has no encounter order, than any element
+     * may be returned.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * terminal operation</a>.
+     *
+     * @return an {@code OptionalInt} describing the first element of this stream,
+     * or an empty {@code OptionalInt} if the stream is empty
+     */
+    OptionalInt findFirst();
+
+    /**
+     * Returns an {@link OptionalInt} describing some element of the stream, or
+     * an empty {@code OptionalInt} if the stream is empty.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * terminal operation</a>.
+     *
+     * <p>The behavior of this operation is explicitly nondeterministic; it is
+     * free to select any element in the stream.  This is to allow for maximal
+     * performance in parallel operations; the cost is that multiple invocations
+     * on the same source may not return the same result.  (If the first element
+     * in the encounter order is desired, use {@link #findFirst()} instead.)
+     *
+     * @return an {@code OptionalInt} describing some element of this stream, or
+     * an empty {@code OptionalInt} if the stream is empty
+     * @see #findFirst()
+     */
+    OptionalInt findAny();
+
+    /**
+     * Returns a {@code LongStream} consisting of the elements of this stream,
+     * converted to {@code long}.
+     *
+     * @return a {@code LongStream} consisting of the elements of this stream,
+     * converted to {@code long}
+     */
+    LongStream longs();
+
+    /**
+     * Returns a {@code DoubleStream} consisting of the elements of this stream,
+     * converted to {@code double}.
+     *
+     * @return a {@code DoubleStream} consisting of the elements of this stream,
+     * converted to {@code double}
+     */
+    DoubleStream doubles();
+
+    /**
+     * Returns a {@code Stream} consisting of the elements of this stream,
+     * each boxed to an {@code Integer}.
+     *
+     * @return a {@code Stream} consistent of the elements of this stream,
+     * each boxed to an {@code Integer}
+     */
+    Stream<Integer> boxed();
+
+    @Override
+    IntStream sequential();
+
+    @Override
+    IntStream parallel();
+
+    @Override
+    PrimitiveIterator.OfInt iterator();
+
+    @Override
+    Spliterator.OfInt spliterator();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/util/stream/LongStream.java	Tue Apr 23 11:13:38 2013 +0100
@@ -0,0 +1,646 @@
+/*
+ * Copyright (c) 2013, 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;
+
+import java.util.LongSummaryStatistics;
+import java.util.OptionalDouble;
+import java.util.OptionalLong;
+import java.util.PrimitiveIterator;
+import java.util.Spliterator;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+import java.util.function.LongBinaryOperator;
+import java.util.function.LongConsumer;
+import java.util.function.LongFunction;
+import java.util.function.LongPredicate;
+import java.util.function.LongToDoubleFunction;
+import java.util.function.LongToIntFunction;
+import java.util.function.LongUnaryOperator;
+import java.util.function.ObjLongConsumer;
+import java.util.function.Supplier;
+
+/**
+ * A sequence of primitive long elements supporting sequential and parallel
+ * bulk operations. Streams support lazy intermediate operations (transforming
+ * a stream to another stream) such as {@code filter} and {@code map}, and terminal
+ * operations (consuming the contents of a stream to produce a result or
+ * side-effect), such as {@code forEach}, {@code findFirst}, and {@code
+ * iterator}.  Once an operation has been performed on a stream, it
+ * is considered <em>consumed</em> and no longer usable for other operations.
+ *
+ * <p>For sequential stream pipelines, all operations are performed in the
+ * <a href="package-summary.html#Ordering">encounter order</a> of the pipeline
+ * source, if the pipeline source has a defined encounter order.
+ *
+ * <p>For parallel stream pipelines, unless otherwise specified, intermediate
+ * stream operations preserve the <a href="package-summary.html#Ordering">
+ * encounter order</a> of their source, and terminal operations
+ * respect the encounter order of their source, if the source
+ * has an encounter order.  Provided that and parameters to stream operations
+ * satisfy the <a href="package-summary.html#NonInterference">non-interference
+ * requirements</a>, and excepting differences arising from the absence of
+ * a defined encounter order, the result of a stream pipeline should be the
+ * stable across multiple executions of the same operations on the same source.
+ * However, the timing and thread in which side-effects occur (for those
+ * operations which are allowed to produce side-effects, such as
+ * {@link #forEach(LongConsumer)}), are explicitly nondeterministic for parallel
+ * execution of stream pipelines.
+ *
+ * <p>Unless otherwise noted, passing a {@code null} argument to any stream
+ * method may result in a {@link NullPointerException}.
+ *
+ * @apiNote
+ * Streams are not data structures; they do not manage the storage for their
+ * elements, nor do they support access to individual elements.  However,
+ * you can use the {@link #iterator()} or {@link #spliterator()} operations to
+ * perform a controlled traversal.
+ *
+ * @since 1.8
+ * @see <a href="package-summary.html">java.util.stream</a>
+ */
+public interface LongStream extends BaseStream<Long, LongStream> {
+
+    /**
+     * Returns a stream consisting of the elements of this stream that match
+     * the given predicate.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param predicate a <a href="package-summary.html#NonInterference">
+     *                  non-interfering, stateless</a> predicate to apply to
+     *                  each element to determine if it should be included
+     * @return the new stream
+     */
+    LongStream filter(LongPredicate predicate);
+
+    /**
+     * Returns a stream consisting of the results of applying the given
+     * function to the elements of this stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to each
+     *               element
+     * @return the new stream
+     */
+    LongStream map(LongUnaryOperator mapper);
+
+    /**
+     * Returns an object-valued {@code Stream} consisting of the results of
+     * applying the given function to the elements of this stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">
+     *     intermediate operation</a>.
+     *
+     * @param <U> the element type of the new stream
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to each
+     *               element
+     * @return the new stream
+     */
+    <U> Stream<U> mapToObj(LongFunction<? extends U> mapper);
+
+    /**
+     * Returns an {@code IntStream} consisting of the results of applying the
+     * given function to the elements of this stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to each
+     *               element
+     * @return the new stream
+     */
+    IntStream mapToInt(LongToIntFunction mapper);
+
+    /**
+     * Returns a {@code DoubleStream} consisting of the results of applying the
+     * given function to the elements of this stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to each
+     *               element
+     * @return the new stream
+     */
+    DoubleStream mapToDouble(LongToDoubleFunction mapper);
+
+    /**
+     * Returns a stream consisting of the results of replacing each element of
+     * this stream with the contents of the stream produced by applying the
+     * provided mapping function to each element.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @apiNote
+     * The {@code flatMap()} operation has the effect of applying a one-to-many
+     * tranformation to the elements of the stream, and then flattening the
+     * resulting elements into a new stream. For example, if {@code orders}
+     * is a stream of purchase orders, and each purchase order contains a
+     * collection of line items, then the following produces a stream of line
+     * items:
+     * <pre>{@code
+     *     orderStream.flatMap(order -> order.getLineItems().stream())...
+     * }</pre>
+     *
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to
+     *               each element which produces an {@code LongStream} of new
+     *               values
+     * @return the new stream
+     * @see Stream#flatMap(Function)
+     */
+    LongStream flatMap(LongFunction<? extends LongStream> mapper);
+
+    /**
+     * Returns a stream consisting of the distinct elements of this stream.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">stateful
+     * intermediate operation</a>.
+     *
+     * @return the new stream
+     */
+    LongStream distinct();
+
+    /**
+     * Returns a stream consisting of the elements of this stream in sorted
+     * order.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">stateful
+     * intermediate operation</a>.
+     *
+     * @return the new stream
+     */
+    LongStream sorted();
+
+    /**
+     * Returns a stream consisting of the elements of this stream, additionally
+     * performing the provided action on each element as elements are consumed
+     * from the resulting stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * <p>For parallel stream pipelines, the action may be called at
+     * whatever time and in whatever thread the element is made available by the
+     * upstream operation.  If the action modifies shared state,
+     * it is responsible for providing the required synchronization.
+     *
+     * @apiNote This method exists mainly to support debugging, where you want
+     * to see the elements as they flow past a certain point in a pipeline:
+     * <pre>{@code
+     *     list.stream()
+     *         .filter(filteringFunction)
+     *         .peek(e -> {System.out.println("Filtered value: " + e); });
+     *         .map(mappingFunction)
+     *         .peek(e -> {System.out.println("Mapped value: " + e); });
+     *         .collect(Collectors.toLongSummaryStastistics());
+     * }</pre>
+     *
+     * @param consumer a <a href="package-summary.html#NonInterference">
+     *                 non-interfering</a> action to perform on the elements as
+     *                 they are consumed from the stream
+     * @return the new stream
+     */
+    LongStream peek(LongConsumer consumer);
+
+    /**
+     * Returns a stream consisting of the elements of this stream, truncated
+     * to be no longer than {@code maxSize} in length.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * stateful intermediate operation</a>.
+     *
+     * @param maxSize the number of elements the stream should be limited to
+     * @return the new stream
+     * @throws IllegalArgumentException if {@code maxSize} is negative
+     */
+    LongStream limit(long maxSize);
+
+    /**
+     * Returns a stream consisting of the remaining elements of this stream
+     * after indexing {@code startInclusive} elements into the stream. If the
+     * {@code startInclusive} index lies past the end of this stream then an
+     * empty stream will be returned.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">stateful
+     * intermediate operation</a>.
+     *
+     * @param startInclusive the number of leading elements to skip
+     * @return the new stream
+     * @throws IllegalArgumentException if {@code startInclusive} is negative
+     */
+    LongStream substream(long startInclusive);
+
+    /**
+     * Returns a stream consisting of the remaining elements of this stream
+     * after indexing {@code startInclusive} elements into the stream and
+     * truncated to contain no more than {@code endExclusive - startInclusive}
+     * elements. If the {@code startInclusive} index lies past the end
+     * of this stream then an empty stream will be returned.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * stateful intermediate operation</a>.
+     *
+     * @param startInclusive the starting position of the substream, inclusive
+     * @param endExclusive the ending position of the substream, exclusive
+     * @return the new stream
+     * @throws IllegalArgumentException if {@code startInclusive} or
+     * {@code endExclusive} is negative or {@code startInclusive} is greater
+     * than {@code endExclusive}
+     */
+    LongStream substream(long startInclusive, long endExclusive);
+
+    /**
+     * Performs an action for each element of this stream.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * <p>For parallel stream pipelines, this operation does <em>not</em>
+     * guarantee to respect the encounter order of the stream, as doing so
+     * would sacrifice the benefit of parallelism.  For any given element, the
+     * action may be performed at whatever time and in whatever thread the
+     * library chooses.  If the action accesses shared state, it is
+     * responsible for providing the required synchronization.
+     *
+     * @param action a <a href="package-summary.html#NonInterference">
+     *               non-interfering</a> action to perform on the elements
+     */
+    void forEach(LongConsumer action);
+
+    /**
+     * Performs an action for each element of this stream, guaranteeing that
+     * each element is processed in encounter order for streams that have a
+     * defined encounter order.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @param action a <a href="package-summary.html#NonInterference">
+     *               non-interfering</a> action to perform on the elements
+     * @see #forEach(LongConsumer)
+     */
+    void forEachOrdered(LongConsumer action);
+
+    /**
+     * Returns an array containing the elements of this stream.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @return an array containing the elements of this stream
+     */
+    long[] toArray();
+
+    /**
+     * Performs a <a href="package-summary.html#Reduction">reduction</a> on the
+     * elements of this stream, using the provided identity value and an
+     * <a href="package-summary.html#Associativity">associative</a>
+     * accumulation function, and returns the reduced value.  This is equivalent
+     * to:
+     * <pre>{@code
+     *     long result = identity;
+     *     for (long element : this stream)
+     *         result = accumulator.apply(result, element)
+     *     return result;
+     * }</pre>
+     *
+     * but is not constrained to execute sequentially.
+     *
+     * <p>The {@code identity} value must be an identity for the accumulator
+     * function. This means that for all {@code x},
+     * {@code accumulator.apply(identity, x)} is equal to {@code x}.
+     * The {@code accumulator} function must be an
+     * <a href="package-summary.html#Associativity">associative</a> function.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @apiNote Sum, min, max, and average are all special cases of reduction.
+     * Summing a stream of numbers can be expressed as:
+     *
+     * <pre>{@code
+     *     long sum = integers.reduce(0, (a, b) -> a+b);
+     * }</pre>
+     *
+     * or more compactly:
+     *
+     * <pre>{@code
+     *     long sum = integers.reduce(0, Long::sum);
+     * }</pre>
+     *
+     * <p>While this may seem a more roundabout way to perform an aggregation
+     * compared to simply mutating a running total in a loop, reduction
+     * operations parallelize more gracefully, without needing additional
+     * synchronization and with greatly reduced risk of data races.
+     *
+     * @param identity the identity value for the accumulating function
+     * @param op an <a href="package-summary.html#Associativity">associative</a>
+     *                    <a href="package-summary.html#NonInterference">non-interfering,
+     *                    stateless</a> function for combining two values
+     * @return the result of the reduction
+     * @see #sum()
+     * @see #min()
+     * @see #max()
+     * @see #average()
+     */
+    long reduce(long identity, LongBinaryOperator op);
+
+    /**
+     * Performs a <a href="package-summary.html#Reduction">reduction</a> on the
+     * elements of this stream, using an
+     * <a href="package-summary.html#Associativity">associative</a> accumulation
+     * function, and returns an {@code OptionalLong} describing the reduced value,
+     * if any. This is equivalent to:
+     * <pre>{@code
+     *     boolean foundAny = false;
+     *     long result = null;
+     *     for (long element : this stream) {
+     *         if (!foundAny) {
+     *             foundAny = true;
+     *             result = element;
+     *         }
+     *         else
+     *             result = accumulator.apply(result, element);
+     *     }
+     *     return foundAny ? OptionalLong.of(result) : OptionalLong.empty();
+     * }</pre>
+     *
+     * but is not constrained to execute sequentially.
+     *
+     * <p>The {@code accumulator} function must be an
+     * <a href="package-summary.html#Associativity">associative</a> function.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @param op an <a href="package-summary.html#Associativity">associative</a>
+     *           <a href="package-summary.html#NonInterference">non-interfering,
+     *           stateless</a> function for combining two values
+     * @return the result of the reduction
+     * @see #reduce(long, LongBinaryOperator)
+     */
+    OptionalLong reduce(LongBinaryOperator op);
+
+    /**
+     * Performs a <a href="package-summary.html#MutableReduction">mutable
+     * reduction</a> operation on the elements of this stream.  A mutable
+     * reduction is one in which the reduced value is a mutable value holder,
+     * such as an {@code ArrayList}, and elements are incorporated by updating
+     * the state of the result, rather than by replacing the result.  This
+     * produces a result equivalent to:
+     * <pre>{@code
+     *     R result = resultFactory.get();
+     *     for (long element : this stream)
+     *         accumulator.accept(result, element);
+     *     return result;
+     * }</pre>
+     *
+     * <p>Like {@link #reduce(long, LongBinaryOperator)}, {@code collect} operations
+     * can be parallelized without requiring additional synchronization.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @param <R> type of the result
+     * @param resultFactory a function that creates a new result container.
+     *                      For a parallel execution, this function may be
+     *                      called multiple times and must return a fresh value
+     *                      each time.
+     * @param accumulator an <a href="package-summary.html#Associativity">associative</a>
+     *                    <a href="package-summary.html#NonInterference">non-interfering,
+     *                    stateless</a> function for incorporating an additional
+     *                    element into a result
+     * @param combiner an <a href="package-summary.html#Associativity">associative</a>
+     *                 <a href="package-summary.html#NonInterference">non-interfering,
+     *                 stateless</a> function for combining two values, which
+     *                 must be compatible with the accumulator function
+     * @return the result of the reduction
+     * @see Stream#collect(Supplier, BiConsumer, BiConsumer)
+     */
+    <R> R collect(Supplier<R> resultFactory,
+                  ObjLongConsumer<R> accumulator,
+                  BiConsumer<R, R> combiner);
+
+    /**
+     * Returns the sum of elements in this stream.  This is a special case
+     * of a <a href="package-summary.html#MutableReduction">reduction</a>
+     * and is equivalent to:
+     * <pre>{@code
+     *     return reduce(0, Long::sum);
+     * }</pre>
+     *
+     * @return the sum of elements in this stream
+     */
+    long sum();
+
+    /**
+     * Returns an {@code OptionalLong} describing the minimum element of this
+     * stream, or an empty optional if this stream is empty.  This is a special
+     * case of a <a href="package-summary.html#MutableReduction">reduction</a>
+     * and is equivalent to:
+     * <pre>{@code
+     *     return reduce(Long::min);
+     * }</pre>
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>.
+     *
+
+     * @return an {@code OptionalLong} containing the minimum element of this
+     * stream, or an empty {@code OptionalLong} if the stream is empty
+     */
+    OptionalLong min();
+
+    /**
+     * Returns an {@code OptionalLong} describing the maximum element of this
+     * stream, or an empty optional if this stream is empty.  This is a special
+     * case of a <a href="package-summary.html#MutableReduction">reduction</a>
+     * and is equivalent to:
+     * <pre>{@code
+     *     return reduce(Long::max);
+     * }</pre>
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal
+     * operation</a>.
+     *
+     * @return an {@code OptionalLong} containing the maximum element of this
+     * stream, or an empty {@code OptionalLong} if the stream is empty
+     */
+    OptionalLong max();
+
+    /**
+     * Returns the count of elements in this stream.  This is a special case of
+     * a <a href="package-summary.html#MutableReduction">reduction</a> and is
+     * equivalent to:
+     * <pre>{@code
+     *     return map(e -> 1L).sum();
+     * }</pre>
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">terminal operation</a>.
+     *
+     * @return the count of elements in this stream
+     */
+    long count();
+
+    /**
+     * Returns an {@code OptionalDouble} describing the average of elements of
+     * this stream, or an empty optional if this stream is empty.  This is a
+     * special case of a
+     * <a href="package-summary.html#MutableReduction">reduction</a>.
+     *
+     * @return an {@code OptionalDouble} containing the average element of this
+     * stream, or an empty optional if the stream is empty
+     */
+    OptionalDouble average();
+
+    /**
+     * Returns a {@code LongSummaryStatistics} describing various summary data
+     * about the elements of this stream.  This is a special case of a
+     * <a href="package-summary.html#MutableReduction">reduction</a>.
+     *
+     * @return a {@code LongSummaryStatistics} describing various summary data
+     * about the elements of this stream
+     */
+    LongSummaryStatistics summaryStatistics();
+
+    /**
+     * Returns whether any elements of this stream match the provided
+     * predicate.  May not evaluate the predicate on all elements if not
+     * necessary for determining the result.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * terminal operation</a>.
+     *
+     * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
+     *                  stateless</a> predicate to apply to elements of this
+     *                  stream
+     * @return {@code true} if any elements of the stream match the provided
+     * predicate otherwise {@code false}
+     */
+    boolean anyMatch(LongPredicate predicate);
+
+    /**
+     * Returns whether all elements of this stream match the provided predicate.
+     * May not evaluate the predicate on all elements if not necessary for
+     * determining the result.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * terminal operation</a>.
+     *
+     * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
+     *                  stateless</a> predicate to apply to elements of this
+     *                  stream
+     * @return {@code true} if all elements of the stream match the provided
+     * predicate otherwise {@code false}
+     */
+    boolean allMatch(LongPredicate predicate);
+
+    /**
+     * Returns whether no elements of this stream match the provided  predicate.
+     * May not evaluate the predicate on all elements if not necessary for
+     * determining the result.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * terminal operation</a>.
+     *
+     * @param predicate a <a href="package-summary.html#NonInterference">non-interfering,
+     *                  stateless</a> predicate to apply to elements of this
+     *                  stream
+     * @return {@code true} if no elements of the stream match the provided
+     * predicate otherwise {@code false}
+     */
+    boolean noneMatch(LongPredicate predicate);
+
+    /**
+     * Returns an {@link OptionalLong} describing the first element of this
+     * stream (in the encounter order), or an empty {@code OptionalLong} if the
+     * stream is empty.  If the stream has no encounter order, than any element
+     * may be returned.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * terminal operation</a>.
+     *
+     * @return an {@code OptionalLong} describing the first element of this
+     * stream, or an empty {@code OptionalLong} if the stream is empty
+     */
+    OptionalLong findFirst();
+
+    /**
+     * Returns an {@link OptionalLong} describing some element of the stream, or
+     * an empty {@code OptionalLong} if the stream is empty.
+     *
+     * <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
+     * terminal operation</a>.
+     *
+     * <p>The behavior of this operation is explicitly nondeterministic; it is
+     * free to select any element in the stream.  This is to allow for maximal
+     * performance in parallel operations; the cost is that multiple invocations
+     * on the same source may not return the same result.  (If the first element
+     * in the encounter order is desired, use {@link #findFirst()} instead.)
+     *
+     * @return an {@code OptionalLong} describing some element of this stream,
+     * or an empty {@code OptionalLong} if the stream is empty
+     * @see #findFirst()
+     */
+    OptionalLong findAny();
+
+    /**
+     * Returns a {@code DoubleStream} consisting of the elements of this stream,
+     * converted to {@code double}.
+     *
+     * @return a {@code DoubleStream} consisting of the elements of this stream,
+     * converted to {@code double}
+     */
+    DoubleStream doubles();
+
+    /**
+     * Returns a {@code Stream} consisting of the elements of this stream,
+     * each boxed to a {@code Long}.
+     *
+     * @return a {@code Stream} consistent of the elements of this stream,
+     * each boxed to {@code Long}
+     */
+    Stream<Long> boxed();
+
+    @Override
+    LongStream sequential();
+
+    @Override
+    LongStream parallel();
+
+    @Override
+    PrimitiveIterator.OfLong iterator();
+
+    @Override
+    Spliterator.OfLong spliterator();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/util/stream/MatchOps.java	Tue Apr 23 11:13:38 2013 +0100
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 2012, 2013, 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;
+
+import java.util.Objects;
+import java.util.Spliterator;
+import java.util.function.DoublePredicate;
+import java.util.function.IntPredicate;
+import java.util.function.LongPredicate;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+
+/**
+ * Factory for instances of a short-circuiting {@code TerminalOp} that implement
+ * quantified predicate matching on the elements of a stream. Supported variants
+ * include match-all, match-any, and match-none.
+ *
+ * @since 1.8
+ */
+final class MatchOps {
+
+    private MatchOps() { }
+
+    /**
+     * Enum describing quantified match options -- all match, any match, none
+     * match.
+     */
+    enum MatchKind {
+        /** Do all elements match the predicate? */
+        ANY(true, true),
+
+        /** Do any elements match the predicate? */
+        ALL(false, false),
+
+        /** Do no elements match the predicate? */
+        NONE(true, false);
+
+        private final boolean stopOnPredicateMatches;
+        private final boolean shortCircuitResult;
+
+        private MatchKind(boolean stopOnPredicateMatches,
+                          boolean shortCircuitResult) {
+            this.stopOnPredicateMatches = stopOnPredicateMatches;
+            this.shortCircuitResult = shortCircuitResult;
+        }
+    }
+
+    /**
+     * Constructs a quantified predicate matcher for a Stream.
+     *
+     * @param <T> the type of stream elements
+     * @param predicate the {@code Predicate} to apply to stream elements
+     * @param matchKind the kind of quantified match (all, any, none)
+     * @return a {@code TerminalOp} implementing the desired quantified match
+     *         criteria
+     */
+    public static <T> TerminalOp<T, Boolean> makeRef(Predicate<? super T> predicate,
+            MatchKind matchKind) {
+        Objects.requireNonNull(predicate);
+        Objects.requireNonNull(matchKind);
+        class MatchSink extends BooleanTerminalSink<T> {
+            MatchSink() {
+                super(matchKind);
+            }
+
+            @Override
+            public void accept(T t) {
+                if (!stop && predicate.test(t) == matchKind.stopOnPredicateMatches) {
+                    stop = true;
+                    value = matchKind.shortCircuitResult;
+                }
+            }
+        }
+
+        // @@@ Workaround for JDK-8011591 -- when fixed, replace s with constructor ref
+        Supplier<BooleanTerminalSink<T>> s = new Supplier<BooleanTerminalSink<T>>() {
+            @Override
+            public BooleanTerminalSink<T> get() {return new MatchSink();}
+        };
+        return new MatchOp<>(StreamShape.REFERENCE, matchKind, s);
+    }
+
+    /**
+     * Constructs a quantified predicate matcher for an {@code IntStream}.
+     *
+     * @param predicate the {@code Predicate} to apply to stream elements
+     * @param matchKind the kind of quantified match (all, any, none)
+     * @return a {@code TerminalOp} implementing the desired quantified match
+     *         criteria
+     */
+    public static TerminalOp<Integer, Boolean> makeInt(IntPredicate predicate,
+                                                       MatchKind matchKind) {
+        Objects.requireNonNull(predicate);
+        Objects.requireNonNull(matchKind);
+        class MatchSink extends BooleanTerminalSink<Integer> implements Sink.OfInt {
+            MatchSink() {
+                super(matchKind);
+            }
+
+            @Override
+            public void accept(int t) {
+                if (!stop && predicate.test(t) == matchKind.stopOnPredicateMatches) {
+                    stop = true;
+                    value = matchKind.shortCircuitResult;
+                }
+            }
+        }
+
+        // @@@ Workaround for JDK-8011591 -- when fixed, replace s with constructor ref
+        Supplier<BooleanTerminalSink<Integer>> s = new Supplier<BooleanTerminalSink<Integer>>() {
+            @Override
+            public BooleanTerminalSink<Integer> get() {return new MatchSink();}
+        };
+        return new MatchOp<>(StreamShape.INT_VALUE, matchKind, s);
+    }
+
+    /**
+     * Constructs a quantified predicate matcher for a {@code LongStream}.
+     *
+     * @param predicate the {@code Predicate} to apply to stream elements
+     * @param matchKind the kind of quantified match (all, any, none)
+     * @return a {@code TerminalOp} implementing the desired quantified match
+     *         criteria
+     */
+    public static TerminalOp<Long, Boolean> makeLong(LongPredicate predicate,
+                                                     MatchKind matchKind) {
+        Objects.requireNonNull(predicate);
+        Objects.requireNonNull(matchKind);
+        class MatchSink extends BooleanTerminalSink<Long> implements Sink.OfLong {
+
+            MatchSink() {
+                super(matchKind);
+            }
+
+            @Override
+            public void accept(long t) {
+                if (!stop && predicate.test(t) == matchKind.stopOnPredicateMatches) {
+                    stop = true;
+                    value = matchKind.shortCircuitResult;
+                }
+            }
+        }
+
+        // @@@ Workaround for JDK-8011591 -- when fixed, replace s with constructor ref
+        Supplier<BooleanTerminalSink<Long>> s = new Supplier<BooleanTerminalSink<Long>>() {
+            @Override
+            public BooleanTerminalSink<Long> get() {return new MatchSink();}
+        };
+        return new MatchOp<>(StreamShape.LONG_VALUE, matchKind, s);
+    }
+
+    /**
+     * Constructs a quantified predicate matcher for a {@code DoubleStream}.
+     *
+     * @param predicate the {@code Predicate} to apply to stream elements
+     * @param matchKind the kind of quantified match (all, any, none)
+     * @return a {@code TerminalOp} implementing the desired quantified match
+     *         criteria
+     */
+    public static TerminalOp<Double, Boolean> makeDouble(DoublePredicate predicate,
+                                                         MatchKind matchKind) {
+        Objects.requireNonNull(predicate);
+        Objects.requireNonNull(matchKind);
+        class MatchSink extends BooleanTerminalSink<Double> implements Sink.OfDouble {
+
+            MatchSink() {
+                super(matchKind);
+            }
+
+            @Override
+            public void accept(double t) {
+                if (!stop && predicate.test(t) == matchKind.stopOnPredicateMatches) {
+                    stop = true;
+                    value = matchKind.shortCircuitResult;
+                }
+            }
+        }
+
+        // @@@ Workaround for JDK-8011591 -- when fixed, replace s with constructor ref
+        Supplier<BooleanTerminalSink<Double>> s = new Supplier<BooleanTerminalSink<Double>>() {
+            @Override
+            public BooleanTerminalSink<Double> get() {return new MatchSink();}
+        };
+        return new MatchOp<>(StreamShape.DOUBLE_VALUE, matchKind, s);
+    }
+
+    /**
+     * A short-circuiting {@code TerminalOp} that evaluates a predicate on the
+     * elements of a stream and determines whether all, any or none of those
+     * elements match the predicate.
+     *
+     * @param <T> the output type of the stream pipeline
+     */
+    private static final class MatchOp<T> implements TerminalOp<T, Boolean> {
+        private final StreamShape inputShape;
+        final MatchKind matchKind;
+        final Supplier<BooleanTerminalSink<T>> sinkSupplier;
+
+        /**
+         * Constructs a {@code MatchOp}.
+         *
+         * @param shape the output shape of the stream pipeline
+         * @param matchKind the kind of quantified match (all, any, none)
+         * @param sinkSupplier {@code Supplier} for a {@code Sink} of the
+         *        appropriate shape which implements the matching operation
+         */
+        MatchOp(StreamShape shape,
+                MatchKind matchKind,
+                Supplier<BooleanTerminalSink<T>> sinkSupplier) {
+            this.inputShape = shape;
+            this.matchKind = matchKind;
+            this.sinkSupplier = sinkSupplier;
+        }
+
+        @Override
+        public int getOpFlags() {
+            return StreamOpFlag.IS_SHORT_CIRCUIT | StreamOpFlag.NOT_ORDERED;
+        }
+
+        @Override
+        public StreamShape inputShape() {
+            return inputShape;
+        }
+
+        @Override
+        public <S> Boolean evaluateSequential(PipelineHelper<T> helper,
+                                              Spliterator<S> spliterator) {
+            return helper.wrapAndCopyInto(sinkSupplier.get(), spliterator).getAndClearState();
+        }
+
+        @Override
+        public <S> Boolean evaluateParallel(PipelineHelper<T> helper,
+                                            Spliterator<S> spliterator) {
+            // Approach for parallel implementation:
+            // - Decompose as per usual
+            // - run match on leaf chunks, call result "b"
+            // - if b == matchKind.shortCircuitOn, complete early and return b
+            // - else if we complete normally, return !shortCircuitOn
+
+            return new MatchTask<>(this, helper, spliterator).invoke();
+        }
+    }
+
+    /**
+     * Boolean specific terminal sink to avoid the boxing costs when returning
+     * results.  Subclasses implement the shape-specific functionality.
+     *
+     * @param <T> The output type of the stream pipeline
+     */
+    private static abstract class BooleanTerminalSink<T> implements Sink<T> {
+        boolean stop;
+        boolean value;
+
+        BooleanTerminalSink(MatchKind matchKind) {
+            value = !matchKind.shortCircuitResult;
+        }
+
+        public boolean getAndClearState() {
+            return value;
+        }
+
+        @Override
+        public boolean cancellationRequested() {
+            return stop;
+        }
+    }
+
+    /**
+     * ForkJoinTask implementation to implement a parallel short-circuiting
+     * quantified match
+     *
+     * @param <P_IN> the type of source elements for the pipeline
+     * @param <P_OUT> the type of output elements for the pipeline
+     */
+    private static final class MatchTask<P_IN, P_OUT>
+            extends AbstractShortCircuitTask<P_IN, P_OUT, Boolean, MatchTask<P_IN, P_OUT>> {
+        private final MatchOp<P_OUT> op;
+
+        /**
+         * Constructor for root node
+         */
+        MatchTask(MatchOp<P_OUT> op, PipelineHelper<P_OUT> helper,
+                  Spliterator<P_IN> spliterator) {
+            super(helper, spliterator);
+            this.op = op;
+        }
+
+        /**
+         * Constructor for non-root node
+         */
+        MatchTask(MatchTask<P_IN, P_OUT> parent, Spliterator<P_IN> spliterator) {
+            super(parent, spliterator);
+            this.op = parent.op;
+        }
+
+        @Override
+        protected MatchTask<P_IN, P_OUT> makeChild(Spliterator<P_IN> spliterator) {
+            return new MatchTask<>(this, spliterator);
+        }
+
+        @Override
+        protected Boolean doLeaf() {
+            boolean b = helper.wrapAndCopyInto(op.sinkSupplier.get(), spliterator).getAndClearState();
+            if (b == op.matchKind.shortCircuitResult)
+                shortCircuit(b);
+            return null;
+        }
+
+        @Override
+        protected Boolean getEmptyResult() {
+            return !op.matchKind.shortCircuitResult;
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/util/stream/Node.java	Tue Apr 23 11:13:38 2013 +0100
@@ -0,0 +1,557 @@
+/*
+ * Copyright (c) 2012, 2013, 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;
+
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.function.IntFunction;
+import java.util.function.LongConsumer;
+
+/**
+ * An immutable container for describing an ordered sequence of elements of some
+ * type {@code T}.
+ *
+ * <p>A {@code Node} contains a fixed number of elements, which can be accessed
+ * via the {@link #count}, {@link #spliterator}, {@link #forEach},
+ * {@link #asArray}, or {@link #copyInto} methods.  A {@code Node} may have zero
+ * or more child {@code Node}s; if it has no children (accessed via
+ * {@link #getChildCount} and {@link #getChild(int)}, it is considered <em>flat
+ * </em> or a <em>leaf</em>; if it has children, it is considered an
+ * <em>internal</em> node.  The size of an internal node is the sum of sizes of
+ * its children.
+ *
+ * @apiNote
+ * <p>A {@code Node} typically does not store the elements directly, but instead
+ * mediates access to one or more existing (effectively immutable) data
+ * structures such as a {@code Collection}, array, or a set of other
+ * {@code Node}s.  Commonly {@code Node}s are formed into a tree whose shape
+ * corresponds to the computation tree that produced the elements that are
+ * contained in the leaf nodes.  The use of {@code Node} within the stream
+ * framework is largely to avoid copying data unnecessarily during parallel
+ * operations.
+ *
+ * @param <T> the type of elements.
+ * @since 1.8
+ */
+interface Node<T> {
+
+    /**
+     * Returns a {@link Spliterator} describing the elements contained in this
+     * {@code Node}.
+     *
+     * @return a {@code Spliterator} describing the elements contained in this
+     *         {@code Node}
+     */
+    Spliterator<T> spliterator();
+
+    /**
+     * Traverses the elements of this node, and invoke the provided
+     * {@code Consumer} with each element.  Elements are provided in encounter
+     * order if the source for the {@code Node} has a defined encounter order.
+     *
+     * @param consumer a {@code Consumer} that is to be invoked with each
+     *        element in this {@code Node}
+     */
+    void forEach(Consumer<? super T> consumer);
+
+    /**
+     * Returns the number of child nodes of this node.
+     *
+     * @implSpec The default implementation returns zero.
+     *
+     * @return the number of child nodes
+     */
+    default int getChildCount() {
+        return 0;
+    }
+
+    /**
+     * Retrieves the child {@code Node} at a given index.
+     *
+     * @implSpec The default implementation always throws
+     * {@code IndexOutOfBoundsException}.
+     *
+     * @param i the index to the child node
+     * @return the child node
+     * @throws IndexOutOfBoundsException if the index is less than 0 or greater
+     *         than or equal to the number of child nodes
+     */
+    default Node<T> getChild(int i) {
+        throw new IndexOutOfBoundsException();
+    }
+
+    /**
+     * Provides an array view of the contents of this node.
+     *
+     * <p>Depending on the underlying implementation, this may return a
+     * reference to an internal array rather than a copy.  Since the returned
+     * array may be shared, the returned array should not be modified.  The
+     * {@code generator} function may be consulted to create the array if a new
+     * array needs to be created.
+     *
+     * @param generator a factory function which takes an integer parameter and
+     *        returns a new, empty array of that size and of the appropriate
+     *        array type
+     * @return an array containing the contents of this {@code Node}
+     */
+    T[] asArray(IntFunction<T[]> generator);
+
+    /**
+     * Copies the content of this {@code Node} into an array, starting at a
+     * given offset into the array.  It is the caller's responsibility to ensure
+     * there is sufficient room in the array.
+     *
+     * @param array the array into which to copy the contents of this
+     *       {@code Node}
+     * @param offset the starting offset within the array
+     * @throws IndexOutOfBoundsException if copying would cause access of data
+     *         outside array bounds
+     * @throws NullPointerException if {@code array} is {@code null}
+     */
+    void copyInto(T[] array, int offset);
+
+    /**
+     * Gets the {@code StreamShape} associated with this {@code Node}.
+     *
+     * @implSpec The default in {@code Node} returns
+     * {@code StreamShape.REFERENCE}
+     *
+     * @return the stream shape associated with this node
+     */
+    default StreamShape getShape() {
+        return StreamShape.REFERENCE;
+    }
+
+    /**
+     * Returns the number of elements contained in this node.
+     *
+     * @return the number of elements contained in this node
+     */
+    long count();
+
+    /**
+     * A mutable builder for a {@code Node} that implements {@link Sink}, which
+     * builds a flat node containing the elements that have been pushed to it.
+     */
+    interface Builder<T> extends Sink<T> {
+
+        /**
+         * Builds the node.  Should be called after all elements have been
+         * pushed and signalled with an invocation of {@link Sink#end()}.
+         *
+         * @return the resulting {@code Node}
+         */
+        Node<T> build();
+
+        /**
+         * Specialized @{code Node.Builder} for int elements
+         */
+        interface OfInt extends Node.Builder<Integer>, Sink.OfInt {
+            @Override
+            Node.OfInt build();
+        }
+
+        /**
+         * Specialized @{code Node.Builder} for long elements
+         */
+        interface OfLong extends Node.Builder<Long>, Sink.OfLong {
+            @Override
+            Node.OfLong build();
+        }
+
+        /**
+         * Specialized @{code Node.Builder} for double elements
+         */
+        interface OfDouble extends Node.Builder<Double>, Sink.OfDouble {
+            @Override
+            Node.OfDouble build();
+        }
+    }
+
+    /**
+     * Specialized {@code Node} for int elements
+     */
+    interface OfInt extends Node<Integer> {
+
+        /**
+         * {@inheritDoc}
+         *
+         * @return a {@link Spliterator.OfInt} describing the elements of this
+         *         node
+         */
+        @Override
+        Spliterator.OfInt spliterator();
+
+        /**
+         * {@inheritDoc}
+         *
+         * @param consumer a {@code Consumer} that is to be invoked with each
+         *        element in this {@code Node}.  If this is an
+         *        {@code IntConsumer}, it is cast to {@code IntConsumer} so the
+         *        elements may be processed without boxing.
+         */
+        @Override
+        default void forEach(Consumer<? super Integer> consumer) {
+            if (consumer instanceof IntConsumer) {
+                forEach((IntConsumer) consumer);
+            }
+            else {
+                if (Tripwire.ENABLED)
+                    Tripwire.trip(getClass(), "{0} calling Node.OfInt.forEachRemaining(Consumer)");
+                spliterator().forEachRemaining(consumer);
+            }
+        }
+
+        /**
+         * Traverses the elements of this node, and invoke the provided
+         * {@code IntConsumer} with each element.
+         *
+         * @param consumer a {@code IntConsumer} that is to be invoked with each
+         *        element in this {@code Node}
+         */
+        void forEach(IntConsumer consumer);
+
+        /**
+         * {@inheritDoc}
+         *
+         * @implSpec the default implementation invokes the generator to create
+         * an instance of an Integer[] array with a length of {@link #count()}
+         * and then invokes {@link #copyInto(Integer[], int)} with that
+         * Integer[] array at an offset of 0.  This is not efficient and it is
+         * recommended to invoke {@link #asIntArray()}.
+         */
+        @Override
+        default Integer[] asArray(IntFunction<Integer[]> generator) {
+            Integer[] boxed = generator.apply((int) count());
+            copyInto(boxed, 0);
+            return boxed;
+        }
+
+        /**
+         * {@inheritDoc}
+         *
+         * @implSpec the default implementation invokes {@link #asIntArray()} to
+         * obtain an int[] array then and copies the elements from that int[]
+         * array into the boxed Integer[] array.  This is not efficient and it
+         * is recommended to invoke {@link #copyInto(int[], int)}.
+         */
+        @Override
+        default void copyInto(Integer[] boxed, int offset) {
+            if (Tripwire.ENABLED)
+                Tripwire.trip(getClass(), "{0} calling Node.OfInt.copyInto(Integer[], int)");
+
+            int[] array = asIntArray();
+            for (int i = 0; i < array.length; i++) {
+                boxed[offset + i] = array[i];
+            }
+        }
+
+        @Override
+        default Node.OfInt getChild(int i) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        /**
+         * Views this node as an int[] array.
+         *
+         * <p>Depending on the underlying implementation this may return a
+         * reference to an internal array rather than a copy.  It is the callers
+         * responsibility to decide if either this node or the array is utilized
+         * as the primary reference for the data.</p>
+         *
+         * @return an array containing the contents of this {@code Node}
+         */
+        int[] asIntArray();
+
+        /**
+         * Copies the content of this {@code Node} into an int[] array, starting
+         * at a given offset into the array.  It is the caller's responsibility
+         * to ensure there is sufficient room in the array.
+         *
+         * @param array the array into which to copy the contents of this
+         *              {@code Node}
+         * @param offset the starting offset within the array
+         * @throws IndexOutOfBoundsException if copying would cause access of
+         *         data outside array bounds
+         * @throws NullPointerException if {@code array} is {@code null}
+         */
+        void copyInto(int[] array, int offset);
+
+        /**
+         * {@inheritDoc}
+         * @implSpec The default in {@code Node.OfInt} returns
+         * {@code StreamShape.INT_VALUE}
+         */
+        default StreamShape getShape() {
+            return StreamShape.INT_VALUE;
+        }
+
+    }
+
+    /**
+     * Specialized {@code Node} for long elements
+     */
+    interface OfLong extends Node<Long> {
+
+        /**
+         * {@inheritDoc}
+         *
+         * @return a {@link Spliterator.OfLong} describing the elements of this
+         *         node
+         */
+        @Override
+        Spliterator.OfLong spliterator();
+
+        /**
+         * {@inheritDoc}
+         *
+         * @param consumer A {@code Consumer} that is to be invoked with each
+         *        element in this {@code Node}.  If this is an
+         *        {@code LongConsumer}, it is cast to {@code LongConsumer} so
+         *        the elements may be processed without boxing.
+         */
+        @Override
+        default void forEach(Consumer<? super Long> consumer) {
+            if (consumer instanceof LongConsumer) {
+                forEach((LongConsumer) consumer);
+            }
+            else {
+                if (Tripwire.ENABLED)
+                    Tripwire.trip(getClass(), "{0} calling Node.OfLong.forEachRemaining(Consumer)");
+                spliterator().forEachRemaining(consumer);
+            }
+        }
+
+        /**
+         * Traverses the elements of this node, and invoke the provided
+         * {@code LongConsumer} with each element.
+         *
+         * @param consumer a {@code LongConsumer} that is to be invoked with
+         *        each element in this {@code Node}
+         */
+        void forEach(LongConsumer consumer);
+
+        /**
+         * {@inheritDoc}
+         *
+         * @implSpec the default implementation invokes the generator to create
+         * an instance of a Long[] array with a length of {@link #count()} and
+         * then invokes {@link #copyInto(Long[], int)} with that Long[] array at
+         * an offset of 0.  This is not efficient and it is recommended to
+         * invoke {@link #asLongArray()}.
+         */
+        @Override
+        default Long[] asArray(IntFunction<Long[]> generator) {
+            Long[] boxed = generator.apply((int) count());
+            copyInto(boxed, 0);
+            return boxed;
+        }
+
+        /**
+         * {@inheritDoc}
+         *
+         * @implSpec the default implementation invokes {@link #asLongArray()}
+         * to obtain a long[] array then and copies the elements from that
+         * long[] array into the boxed Long[] array.  This is not efficient and
+         * it is recommended to invoke {@link #copyInto(long[], int)}.
+         */
+        @Override
+        default void copyInto(Long[] boxed, int offset) {
+            if (Tripwire.ENABLED)
+                Tripwire.trip(getClass(), "{0} calling Node.OfInt.copyInto(Long[], int)");
+
+            long[] array = asLongArray();
+            for (int i = 0; i < array.length; i++) {
+                boxed[offset + i] = array[i];
+            }
+        }
+
+        @Override
+        default Node.OfLong getChild(int i) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        /**
+         * Views this node as a long[] array.
+         *
+         * <p/>Depending on the underlying implementation this may return a
+         * reference to an internal array rather than a copy. It is the callers
+         * responsibility to decide if either this node or the array is utilized
+         * as the primary reference for the data.
+         *
+         * @return an array containing the contents of this {@code Node}
+         */
+        long[] asLongArray();
+
+        /**
+         * Copies the content of this {@code Node} into a long[] array, starting
+         * at a given offset into the array.  It is the caller's responsibility
+         * to ensure there is sufficient room in the array.
+         *
+         * @param array the array into which to copy the contents of this
+         *        {@code Node}
+         * @param offset the starting offset within the array
+         * @throws IndexOutOfBoundsException if copying would cause access of
+         *         data outside array bounds
+         * @throws NullPointerException if {@code array} is {@code null}
+         */
+        void copyInto(long[] array, int offset);
+
+        /**
+         * {@inheritDoc}
+         * @implSpec The default in {@code Node.OfLong} returns
+         * {@code StreamShape.LONG_VALUE}
+         */
+        default StreamShape getShape() {
+            return StreamShape.LONG_VALUE;
+        }
+
+
+    }
+
+    /**
+     * Specialized {@code Node} for double elements
+     */
+    interface OfDouble extends Node<Double> {
+
+        /**
+         * {@inheritDoc}
+         *
+         * @return A {@link Spliterator.OfDouble} describing the elements of
+         *         this node
+         */
+        @Override
+        Spliterator.OfDouble spliterator();
+
+        /**
+         * {@inheritDoc}
+         *
+         * @param consumer A {@code Consumer} that is to be invoked with each
+         *        element in this {@code Node}.  If this is an
+         *        {@code DoubleConsumer}, it is cast to {@code DoubleConsumer}
+         *        so the elements may be processed without boxing.
+         */
+        @Override
+        default void forEach(Consumer<? super Double> consumer) {
+            if (consumer instanceof DoubleConsumer) {
+                forEach((DoubleConsumer) consumer);
+            }
+            else {
+                if (Tripwire.ENABLED)
+                    Tripwire.trip(getClass(), "{0} calling Node.OfLong.forEachRemaining(Consumer)");
+                spliterator().forEachRemaining(consumer);
+            }
+        }
+
+        /**
+         * Traverses the elements of this node, and invoke the provided
+         * {@code DoubleConsumer} with each element.
+         *
+         * @param consumer A {@code DoubleConsumer} that is to be invoked with
+         *        each element in this {@code Node}
+         */
+        void forEach(DoubleConsumer consumer);
+
+        //
+
+        /**
+         * {@inheritDoc}
+         *
+         * @implSpec the default implementation invokes the generator to create
+         * an instance of a Double[] array with a length of {@link #count()} and
+         * then invokes {@link #copyInto(Double[], int)} with that Double[]
+         * array at an offset of 0.  This is not efficient and it is recommended
+         * to invoke {@link #asDoubleArray()}.
+         */
+        @Override
+        default Double[] asArray(IntFunction<Double[]> generator) {
+            Double[] boxed = generator.apply((int) count());
+            copyInto(boxed, 0);
+            return boxed;
+        }
+
+        /**
+         * {@inheritDoc}
+         *
+         * @implSpec the default implementation invokes {@link #asDoubleArray()}
+         * to obtain a double[] array then and copies the elements from that
+         * double[] array into the boxed Double[] array.  This is not efficient
+         * and it is recommended to invoke {@link #copyInto(double[], int)}.
+         */
+        @Override
+        default void copyInto(Double[] boxed, int offset) {
+            if (Tripwire.ENABLED)
+                Tripwire.trip(getClass(), "{0} calling Node.OfDouble.copyInto(Double[], int)");
+
+            double[] array = asDoubleArray();
+            for (int i = 0; i < array.length; i++) {
+                boxed[offset + i] = array[i];
+            }
+        }
+
+        @Override
+        default Node.OfDouble getChild(int i) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        /**
+         * Views this node as a double[] array.
+         *
+         * <p/>Depending on the underlying implementation this may return a
+         * reference to an internal array rather than a copy.  It is the callers
+         * responsibility to decide if either this node or the array is utilized
+         * as the primary reference for the data.
+         *
+         * @return an array containing the contents of this {@code Node}
+         */
+        double[] asDoubleArray();
+
+        /**
+         * Copies the content of this {@code Node} into a double[] array, starting
+         * at a given offset into the array.  It is the caller's responsibility
+         * to ensure there is sufficient room in the array.
+         *
+         * @param array the array into which to copy the contents of this
+         *        {@code Node}
+         * @param offset the starting offset within the array
+         * @throws IndexOutOfBoundsException if copying would cause access of
+         *         data outside array bounds
+         * @throws NullPointerException if {@code array} is {@code null}
+         */
+        void copyInto(double[] array, int offset);
+
+        /**
+         * {@inheritDoc}
+         *
+         * @implSpec The default in {@code Node.OfDouble} returns
+         * {@code StreamShape.DOUBLE_VALUE}
+         */
+        default StreamShape getShape() {
+            return StreamShape.DOUBLE_VALUE;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/util/stream/PipelineHelper.java	Tue Apr 23 11:13:38 2013 +0100
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2012, 2013, 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;
+
+import java.util.Spliterator;
+import java.util.function.IntFunction;
+
+/**
+ * Helper class for executing <a href="package-summary.html#StreamPipelines">
+ * stream pipelines</a>, capturing all of the information about a stream
+ * pipeline (output shape, intermediate operations, stream flags, parallelism,
+ * etc) in one place.
+ *
+ * <p>
+ * A {@code PipelineHelper} describes the initial segment of a stream pipeline,
+ * including its source, intermediate operations, and may additionally
+ * incorporate information about the terminal (or stateful) operation which
+ * follows the last intermediate operation described by this
+ * {@code PipelineHelper}. The {@code PipelineHelper} is passed to the
+ * {@link TerminalOp#evaluateParallel(PipelineHelper, java.util.Spliterator)},
+ * {@link TerminalOp#evaluateSequential(PipelineHelper, java.util.Spliterator)},
+ * and {@link AbstractPipeline#opEvaluateParallel(PipelineHelper, java.util.Spliterator,
+ * java.util.function.IntFunction)}, methods, which can use the
+ * {@code PipelineHelper} to access information about the pipeline such as
+ * input shape, output shape, stream flags, and size, and use the helper methods
+ * such as {@link #wrapAndCopyInto(Sink, Spliterator)},
+ * {@link #copyInto(Sink, Spliterator)}, and {@link #wrapSink(Sink)} to execute
+ * pipeline operations.
+ *
+ * @param <P_OUT> type of output elements from the pipeline
+ * @since 1.8
+ */
+abstract class PipelineHelper<P_OUT> {
+
+    /**
+     * Gets the combined stream and operation flags for the output of the described
+     * pipeline.  This will incorporate stream flags from the stream source, all
+     * the intermediate operations and the terminal operation.
+     *
+     * @return the combined stream and operation flags
+     * @see StreamOpFlag
+     */
+    abstract int getStreamAndOpFlags();
+
+    /**
+     * Returns the exact output size of the portion of the output resulting from
+     * applying the pipeline stages described by this {@code PipelineHelper} to
+     * the the portion of the input described by the provided
+     * {@code Spliterator}, if known.  If not known or known infinite, will
+     * return {@code -1}.
+     *
+     * @apiNote
+     * The exact output size is known if the {@code Spliterator} has the
+     * {@code SIZED} characteristic, and the operation flags
+     * {@link StreamOpFlag#SIZED} is known on the combined stream and operation
+     * flags.
+     *
+     * @param spliterator the spliterator describing the relevant portion of the
+     *        source data
+     * @return the exact size if known, or -1 if infinite or unknown
+     */
+    abstract<P_IN> long exactOutputSizeIfKnown(Spliterator<P_IN> spliterator);
+
+    /**
+     * Applies the pipeline stages described by this {@code PipelineHelper} to
+     * the provided {@code Spliterator} and send the results to the provided
+     * {@code Sink}.
+     *
+     * @implSpec
+     * The implementation behaves as if:
+     * <pre>{@code
+     *     intoWrapped(wrapSink(sink), spliterator);
+     * }</pre>
+     *
+     * @param sink the {@code Sink} to receive the results
+     * @param spliterator the spliterator describing the source input to process
+     */
+    abstract<P_IN, S extends Sink<P_OUT>> S wrapAndCopyInto(S sink, Spliterator<P_IN> spliterator);
+
+    /**
+     * Pushes elements obtained from the {@code Spliterator} into the provided
+     * {@code Sink}.  If the stream pipeline is known to have short-circuiting
+     * stages in it (see {@link StreamOpFlag#SHORT_CIRCUIT}), the
+     * {@link Sink#cancellationRequested()} is checked after each
+     * element, stopping if cancellation is requested.
+     *
+     * @implSpec
+     * This method conforms to the {@code Sink} protocol of calling
+     * {@code Sink.begin} before pushing elements, via {@code Sink.accept}, and
+     * calling {@code Sink.end} after all elements have been pushed.
+     *
+     * @param wrappedSink the destination {@code Sink}
+     * @param spliterator the source {@code Spliterator}
+     */
+    abstract<P_IN> void copyInto(Sink<P_IN> wrappedSink, Spliterator<P_IN> spliterator);
+
+    /**
+     * Pushes elements obtained from the {@code Spliterator} into the provided
+     * {@code Sink}, checking {@link Sink#cancellationRequested()} after each
+     * element, and stopping if cancellation is requested.
+     *
+     * @implSpec
+     * This method conforms to the {@code Sink} protocol of calling
+     * {@code Sink.begin} before pushing elements, via {@code Sink.accept}, and
+     * calling {@code Sink.end} after all elements have been pushed or if
+     * cancellation is requested.
+     *
+     * @param wrappedSink the destination {@code Sink}
+     * @param spliterator the source {@code Spliterator}
+     */
+    abstract <P_IN> void copyIntoWithCancel(Sink<P_IN> wrappedSink, Spliterator<P_IN> spliterator);
+
+    /**
+     * Takes a {@code Sink} that accepts elements of the output type of the
+     * {@code PipelineHelper}, and wrap it with a {@code Sink} that accepts
+     * elements of the input type and implements all the intermediate operations
+     * described by this {@code PipelineHelper}, delivering the result into the
+     * provided {@code Sink}.
+     *
+     * @param sink the {@code Sink} to receive the results
+     * @return a {@code Sink} that implements the pipeline stages and sends
+     *         results to the provided {@code Sink}
+     */
+    abstract<P_IN> Sink<P_IN> wrapSink(Sink<P_OUT> sink);
+
+    /**
+     * Constructs a @{link Node.Builder} compatible with the output shape of
+     * this {@code PipelineHelper}.
+     *
+     * @param exactSizeIfKnown if >=0 then a builder will be created that has a
+     *        fixed capacity of exactly sizeIfKnown elements; if < 0 then the
+     *        builder has variable capacity.  A fixed capacity builder will fail
+     *        if an element is added after the builder has reached capacity.
+     * @param generator a factory function for array instances
+     * @return a {@code Node.Builder} compatible with the output shape of this
+     *         {@code PipelineHelper}
+     */
+    abstract Node.Builder<P_OUT> makeNodeBuilder(long exactSizeIfKnown,
+                                                 IntFunction<P_OUT[]> generator);
+
+    /**
+     * Collects all output elements resulting from applying the pipeline stages
+     * to the source {@code Spliterator} into a {@code Node}.
+     *
+     * @implNote
+     * If the pipeline has no intermediate operations and the source is backed
+     * by a {@code Node} then that {@code Node} will be returned (or flattened
+     * and then returned). This reduces copying for a pipeline consisting of a
+     * stateful operation followed by a terminal operation that returns an
+     * array, such as:
+     * <pre>{@code
+     *     stream.sorted().toArray();
+     * }</pre>
+     *
+     * @param spliterator the source {@code Spliterator}
+     * @param flatten if true and the pipeline is a parallel pipeline then the
+     *        {@code Node} returned will contain no children, otherwise the
+     *        {@code Node} may represent the root in a tree that reflects the
+     *        shape of the computation tree.
+     * @param generator a factory function for array instances
+     * @return the {@code Node} containing all output elements
+     */
+    abstract<P_IN> Node<P_OUT> evaluate(Spliterator<P_IN> spliterator,
+                                        boolean flatten,
+                                        IntFunction<P_OUT[]> generator);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/util/stream/Sink.java	Tue Apr 23 11:13:38 2013 +0100
@@ -0,0 +1,362 @@
+/*
+ * Copyright (c) 2012, 2013, 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;
+
+import java.util.Objects;
+import java.util.function.Consumer;
+import java.util.function.DoubleConsumer;
+import java.util.function.IntConsumer;
+import java.util.function.LongConsumer;
+
+/**
+ * An extension of {@link Consumer} used to conduct values through the stages of
+ * a stream pipeline, with additional methods to manage size information,
+ * control flow, etc.  Before calling the {@code accept()} method on a
+ * {@code Sink} for the first time, you must first call the {@code begin()}
+ * method to inform it that data is coming (optionally informing the sink how
+ * much data is coming), and after all data has been sent, you must call the
+ * {@code end()} method.  After calling {@code end()}, you should not call
+ * {@code accept()} without again calling {@code begin()}.  {@code Sink} also
+ * offers a mechanism by which the sink can cooperatively signal that it does
+ * not wish to receive any more data (the {@code cancellationRequested()}
+ * method), which a source can poll before sending more data to the
+ * {@code Sink}.
+ *
+ * <p>A sink may be in one of two states: an initial state and an active state.
+ * It starts out in the initial state; the {@code begin()} method transitions
+ * it to the active state, and the {@code end()} method transitions it back into
+ * the initial state, where it can be re-used.  Data-accepting methods (such as
+ * {@code accept()} are only valid in the active state.
+ *
+ * @apiNote
+ * A stream pipeline consists of a source, zero or more intermediate stages
+ * (such as filtering or mapping), and a terminal stage, such as reduction or
+ * for-each.  For concreteness, consider the pipeline:
+ *
+ * <pre>{@code
+ *     int longestStringLengthStartingWithA
+ *         = strings.stream()
+ *                  .filter(s -> s.startsWith("A"))
+ *                  .mapToInt(String::length)
+ *                  .max();
+ * }</pre>
+ *
+ * <p>Here, we have three stages, filtering, mapping, and reducing.  The
+ * filtering stage consumes strings and emits a subset of those strings; the
+ * mapping stage consumes strings and emits ints; the reduction stage consumes
+ * those ints and computes the maximal value.
+ *
+ * <p>A {@code Sink} instance is used to represent each stage of this pipeline,
+ * whether the stage accepts objects, ints, longs, or doubles.  Sink has entry
+ * points for {@code accept(Object)}, {@code accept(int)}, etc, so that we do
+ * not need a specialized interface for each primitive specialization.  (It
+ * might be called a "kitchen sink" for this omnivorous tendency.)  The entry
+ * point to the pipeline is the {@code Sink} for the filtering stage, which
+ * sends some elements "downstream" -- into the {@code Sink} for the mapping
+ * stage, which in turn sends integral values downstream into the {@code Sink}
+ * for the reduction stage. The {@code Sink} implementations associated with a
+ * given stage is expected to know the data type for the next stage, and call
+ * the correct {@code accept} method on its downstream {@code Sink}.  Similarly,
+ * each stage must implement the correct {@code accept} method corresponding to
+ * the data type it accepts.
+ *
+ * <p>The specialized subtypes such as {@link Sink.OfInt} override
+ * {@code accept(Object)} to call the appropriate primitive specialization of
+ * {@code accept}, implement the appropriate primitive specialization of
+ * {@code Consumer}, and re-abstract the appropriate primitive specialization of
+ * {@code accept}.
+ *
+ * <p>The chaining subtypes such as {@link ChainedInt} not only implement
+ * {@code Sink.OfInt}, but also maintain a {@code downstream} field which
+ * represents the downstream {@code Sink}, and implement the methods
+ * {@code begin()}, {@code end()}, and {@code cancellationRequested()} to
+ * delegate to the downstream {@code Sink}.  Most implementations of
+ * intermediate operations will use these chaining wrappers.  For example, the
+ * mapping stage in the above example would look like:
+ *
+ * <pre>{@code
+ *     IntSink is = new Sink.ChainedReference<U>(sink) {
+ *         public void accept(U u) {
+ *             downstream.accept(mapper.applyAsInt(u));
+ *         }
+ *     };
+ * }</pre>
+ *
+ * <p>Here, we implement {@code Sink.ChainedReference<U>}, meaning that we expect
+ * to receive elements of type {@code U} as input, and pass the downstream sink
+ * to the constructor.  Because the next stage expects to receive integers, we
+ * must call the {@code accept(int)} method when emitting values to the downstream.
+ * The {@code accept()} method applies the mapping function from {@code U} to
+ * {@code int} and passes the resulting value to the downstream {@code Sink}.
+ *
+ * @param <T> type of elements for value streams
+ * @since 1.8
+ */
+interface Sink<T> extends Consumer<T> {
+    /**
+     * Resets the sink state to receive a fresh data set.  This must be called
+     * before sending any data to the sink.  After calling {@link #end()},
+     * you may call this method to reset the sink for another calculation.
+     * @param size The exact size of the data to be pushed downstream, if
+     * known or {@code -1} if unknown or infinite.
+     *
+     * <p>Prior to this call, the sink must be in the initial state, and after
+     * this call it is in the active state.
+     */
+    default void begin(long size) {}
+
+    /**
+     * Indicates that all elements have been pushed.  If the {@code Sink} is
+     * stateful, it should send any stored state downstream at this time, and
+     * should clear any accumulated state (and associated resources).
+     *
+     * <p>Prior to this call, the sink must be in the active state, and after
+     * this call it is returned to the initial state.
+     */
+    default void end() {}
+
+    /**
+     * Indicates that this {@code Sink} does not wish to receive any more data.
+     *
+     * @implSpec The default implementation always returns false.
+     *
+     * @return true if cancellation is requested
+     */
+    default boolean cancellationRequested() {
+        return false;
+    }
+
+    /**
+     * Accepts an int value.
+     *
+     * @implSpec The default implementation throws IllegalStateException.
+     *
+     * @throws IllegalStateException if this sink does not accept int values
+     */
+    default void accept(int value) {
+        throw new IllegalStateException("called wrong accept method");
+    }
+
+    /**
+     * Accepts a long value.
+     *
+     * @implSpec The default implementation throws IllegalStateException.
+     *
+     * @throws IllegalStateException if this sink does not accept long values
+     */
+    default void accept(long value) {
+        throw new IllegalStateException("called wrong accept method");
+    }
+
+    /**
+     * Accepts a double value.
+     *
+     * @implSpec The default implementation throws IllegalStateException.
+     *
+     * @throws IllegalStateException if this sink does not accept double values
+     */
+    default void accept(double value) {
+        throw new IllegalStateException("called wrong accept method");
+    }
+
+    /**
+     * {@code Sink} that implements {@code Sink<Integer>}, re-abstracts
+     * {@code accept(int)}, and wires {@code accept(Integer)} to bridge to
+     * {@code accept(int)}.
+     */
+    interface OfInt extends Sink<Integer>, IntConsumer {
+        @Override
+        void accept(int value);
+
+        @Override
+        default void accept(Integer i) {
+            if (Tripwire.ENABLED)
+                Tripwire.trip(getClass(), "{0} calling Sink.OfInt.accept(Integer)");
+            accept(i.intValue());
+        }
+    }
+
+    /**
+     * {@code Sink} that implements {@code Sink<Long>}, re-abstracts
+     * {@code accept(long)}, and wires {@code accept(Long)} to bridge to
+     * {@code accept(long)}.
+     */
+    interface OfLong extends Sink<Long>, LongConsumer {
+        @Override
+        void accept(long value);
+
+        @Override
+        default void accept(Long i) {
+            if (Tripwire.ENABLED)
+                Tripwire.trip(getClass(), "{0} calling Sink.OfLong.accept(Long)");
+            accept(i.longValue());
+        }
+    }
+
+    /**
+     * {@code Sink} that implements {@code Sink<Double>}, re-abstracts
+     * {@code accept(double)}, and wires {@code accept(Double)} to bridge to
+     * {@code accept(double)}.
+     */
+    interface OfDouble extends Sink<Double>, DoubleConsumer {
+        @Override
+        void accept(double value);
+
+        @Override
+        default void accept(Double i) {
+            if (Tripwire.ENABLED)
+                Tripwire.trip(getClass(), "{0} calling Sink.OfDouble.accept(Double)");
+            accept(i.doubleValue());
+        }
+    }
+
+    /**
+     * Abstract {@code Sink} implementation for creating chains of
+     * sinks.  The {@code begin}, {@code end}, and
+     * {@code cancellationRequested} methods are wired to chain to the
+     * downstream {@code Sink}.  This implementation takes a downstream
+     * {@code Sink} of unknown input shape and produces a {@code Sink<T>}.  The
+     * implementation of the {@code accept()} method must call the correct
+     * {@code accept()} method on the downstream {@code Sink}.
+     */
+    static abstract class ChainedReference<T> implements Sink<T> {
+        protected final Sink downstream;
+
+        public ChainedReference(Sink downstream) {
+            this.downstream = Objects.requireNonNull(downstream);
+        }
+
+        @Override
+        public void begin(long size) {
+            downstream.begin(size);
+        }
+
+        @Override
+        public void end() {
+            downstream.end();
+        }
+
+        @Override
+        public boolean cancellationRequested() {
+            return downstream.cancellationRequested();
+        }
+    }
+
+    /**
+     * Abstract {@code Sink} implementation designed for creating chains of
+     * sinks.  The {@code begin}, {@code end}, and
+     * {@code cancellationRequested} methods are wired to chain to the
+     * downstream {@code Sink}.  This implementation takes a downstream
+     * {@code Sink} of unknown input shape and produces a {@code Sink.OfInt}.
+     * The implementation of the {@code accept()} method must call the correct
+     * {@code accept()} method on the downstream {@code Sink}.
+     */
+    static abstract class ChainedInt implements Sink.OfInt {
+        protected final Sink downstream;
+
+        public ChainedInt(Sink downstream) {
+            this.downstream = Objects.requireNonNull(downstream);
+        }
+
+        @Override
+        public void begin(long size) {
+            downstream.begin(size);
+        }
+
+        @Override
+        public void end() {
+            downstream.end();
+        }
+
+        @Override
+        public boolean cancellationRequested() {
+            return downstream.cancellationRequested();
+        }
+    }
+
+    /**
+     * Abstract {@code Sink} implementation designed for creating chains of
+     * sinks.  The {@code begin}, {@code end}, and
+     * {@code cancellationRequested} methods are wired to chain to the
+     * downstream {@code Sink}.  This implementation takes a downstream
+     * {@code Sink} of unknown input shape and produces a {@code Sink.OfLong}.
+     * The implementation of the {@code accept()} method must call the correct
+     * {@code accept()} method on the downstream {@code Sink}.
+     */
+    static abstract class ChainedLong implements Sink.OfLong {
+        protected final Sink downstream;
+
+        public ChainedLong(Sink downstream) {
+            this.downstream = Objects.requireNonNull(downstream);
+        }
+
+        @Override
+        public void begin(long size) {
+            downstream.begin(size);
+        }
+
+        @Override
+        public void end() {
+            downstream.end();
+        }
+
+        @Override
+        public boolean cancellationRequested() {
+            return downstream.cancellationRequested();
+        }
+    }
+
+    /**
+     * Abstract {@code Sink} implementation designed for creating chains of
+     * sinks.  The {@code begin}, {@code end}, and
+     * {@code cancellationRequested} methods are wired to chain to the
+     * downstream {@code Sink}.  This implementation takes a downstream
+     * {@code Sink} of unknown input shape and produces a {@code Sink.OfDouble}.
+     * The implementation of the {@code accept()} method must call the correct
+     * {@code accept()} method on the downstream {@code Sink}.
+     */
+    static abstract class ChainedDouble implements Sink.OfDouble {
+        protected final Sink downstream;
+
+        public ChainedDouble(Sink downstream) {
+            this.downstream = Objects.requireNonNull(downstream);
+        }
+
+        @Override
+        public void begin(long size) {
+            downstream.begin(size);
+        }
+
+        @Override
+        public void end() {
+            downstream.end();
+        }
+
+        @Override
+        public boolean cancellationRequested() {
+            return downstream.cancellationRequested();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/util/stream/Stream.java	Tue Apr 23 11:13:38 2013 +0100
@@ -0,0 +1,782 @@
+/*
+ * Copyright (c) 2012, 2013, 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;
+
+import java.util.Comparator;
+import java.util.Optional;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.BinaryOperator;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.IntFunction;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongFunction;
+
+// @@@ Specification to-do list @@@
+// - Describe the difference between sequential and parallel streams
+// - More general information about reduce, better definitions for associativity, more description of
+//   how reduce employs parallelism, more examples
+// - Role of stream flags in various operations, specifically ordering
+//   - Whether each op preserves encounter order
+// @@@ Specification to-do list @@@
+
+/**
+ * A sequence of elements supporting sequential and parallel bulk operations.
+ * Streams support lazy intermediate operations (transforming a stream to
+ * another stream) such as {@code filter} and {@code map}, and terminal
+ * operations (consuming the contents of a stream to produce a result or
+ * side-effect), such as {@code forEach}, {@code findFirst}, and {@code
+ * iterator}.  Once an operation has been performed on a stream, it
+ * is considered <em>consumed</em> and no longer usable for other operations.
+ *
+ * <p>For sequential stream pipelines, all operations are performed in the
+ * <a href="package-summary.html#Ordering">encounter order</a> of the pipeline
+ * source, if the pipeline source has a defined encounter order.
+ *
+ * <p>For parallel stream pipelines, unless otherwise specified, intermediate
+ * stream operations preserve the <a href="package-summary.html#Ordering">
+ * encounter order</a> of their source, and terminal operations
+ * respect the encounter order of their source, if the source
+ * has an encounter order.  Provided that and parameters to stream operations
+ * satisfy the <a href="package-summary.html#NonInterference">non-interference
+ * requirements</a>, and excepting differences arising from the absence of
+ * a defined encounter order, the result of a stream pipeline should be the
+ * stable across multiple executions of the same operations on the same source.
+ * However, the timing and thread in which side-effects occur (for those
+ * operations which are allowed to produce side-effects, such as
+ * {@link #forEach(Consumer)}), are explicitly nondeterministic for parallel
+ * execution of stream pipelines.
+ *
+ * <p>Unless otherwise noted, passing a {@code null} argument to any stream
+ * method may result in a {@link NullPointerException}.
+ *
+ * @apiNote
+ * Streams are not data structures; they do not manage the storage for their
+ * elements, nor do they support access to individual elements.  However,
+ * you can use the {@link #iterator()} or {@link #spliterator()} operations to
+ * perform a controlled traversal.
+ *
+ * @param <T> type of elements
+ * @since 1.8
+ * @see <a href="package-summary.html">java.util.stream</a>
+ */
+public interface Stream<T> extends BaseStream<T, Stream<T>> {
+
+    /**
+     * Returns a stream consisting of the elements of this stream that match
+     * the given predicate.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param predicate a <a href="package-summary.html#NonInterference">
+     *                  non-interfering, stateless</a> predicate to apply to
+     *                  each element to determine if it should be included
+     * @return the new stream
+     */
+    Stream<T> filter(Predicate<? super T> predicate);
+
+    /**
+     * Returns a stream consisting of the results of applying the given
+     * function to the elements of this stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param <R> The element type of the new stream
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to each
+     *               element
+     * @return the new stream
+     */
+    <R> Stream<R> map(Function<? super T, ? extends R> mapper);
+
+    /**
+     * Returns an {@code IntStream} consisting of the results of applying the
+     * given function to the elements of this stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">
+     *     intermediate operation</a>.
+     *
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to each
+     *               element
+     * @return the new stream
+     */
+    IntStream mapToInt(ToIntFunction<? super T> mapper);
+
+    /**
+     * Returns a {@code LongStream} consisting of the results of applying the
+     * given function to the elements of this stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to each
+     *               element
+     * @return the new stream
+     */
+    LongStream mapToLong(ToLongFunction<? super T> mapper);
+
+    /**
+     * Returns a {@code DoubleStream} consisting of the results of applying the
+     * given function to the elements of this stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to each
+     *               element
+     * @return the new stream
+     */
+    DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper);
+
+    /**
+     * Returns a stream consisting of the results of replacing each element of
+     * this stream with the contents of the stream produced by applying the
+     * provided mapping function to each element.  If the result of the mapping
+     * function is {@code null}, this is treated as if the result is an empty
+     * stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @apiNote
+     * The {@code flatMap()} operation has the effect of applying a one-to-many
+     * tranformation to the elements of the stream, and then flattening the
+     * resulting elements into a new stream. For example, if {@code orders}
+     * is a stream of purchase orders, and each purchase order contains a
+     * collection of line items, then the following produces a stream of line
+     * items:
+     * <pre>{@code
+     *     orderStream.flatMap(order -> order.getLineItems().stream())...
+     * }</pre>
+     *
+     * @param <R> The element type of the new stream
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to each
+     *               element which produces a stream of new values
+     * @return the new stream
+     */
+    <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
+
+    /**
+     * Returns an {@code IntStream} consisting of the results of replacing each
+     * element of this stream with the contents of the stream produced by
+     * applying the provided mapping function to each element.  If the result of
+     * the mapping function is {@code null}, this is treated as if the result is
+     * an empty stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to each
+     *               element which produces a stream of new values
+     * @return the new stream
+     */
+    IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper);
+
+    /**
+     * Returns a {@code LongStream} consisting of the results of replacing each
+     * element of this stream with the contents of the stream produced
+     * by applying the provided mapping function to each element.  If the result
+     * of the mapping function is {@code null}, this is treated as if the
+     * result is an empty stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to
+     *               each element which produces a stream of new values
+     * @return the new stream
+     */
+    LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper);
+
+    /**
+     * Returns a {@code DoubleStream} consisting of the results of replacing each
+     * element of this stream with the contents of the stream produced
+     * by applying the provided mapping function to each element.  If the result
+     * of the mapping function is {@code null}, this is treated as if the result
+     * is an empty stream.
+     *
+     * <p>This is an <a href="package-summary.html#StreamOps">intermediate
+     * operation</a>.
+     *
+     * @param mapper a <a href="package-summary.html#NonInterference">
+     *               non-interfering, stateless</a> function to apply to each
+     *               element which produces a stream of new values
+     * @return the new stream
+     */
+    DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper);
+